From d67a9ccdb538299bc082d63b9043772f813607ae Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Thu, 25 Apr 2019 08:28:45 +0300
Subject: [PATCH 01/75] Backed out changeset: ce73fd40aa54

--HG--
branch : develop
---
 code/nel/src/misc/file.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/code/nel/src/misc/file.cpp b/code/nel/src/misc/file.cpp
index 54ffdfbc6..414a10e5a 100644
--- a/code/nel/src/misc/file.cpp
+++ b/code/nel/src/misc/file.cpp
@@ -185,7 +185,7 @@ bool		CIFile::open(const std::string &path, bool text)
 
 	// Bigfile or xml pack access requested ?
 	string::size_type pos;
-	if (!CFile::fileExists(path) && (pos = path.find('@')) != string::npos)
+	if ((pos = path.find('@')) != string::npos)
 	{
 		// check for a double @ to identify XML pack file
 		if (pos+1 < path.size() && path[pos+1] == '@')

From f065b7f7479aa2da1691a8290bfd0e9fd2d67c71 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Thu, 25 Apr 2019 08:38:23 +0300
Subject: [PATCH 02/75] Fixed: Opening local file with @ char in filename

--HG--
branch : develop
---
 code/nel/src/misc/file.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/code/nel/src/misc/file.cpp b/code/nel/src/misc/file.cpp
index 414a10e5a..7eae0f6a5 100644
--- a/code/nel/src/misc/file.cpp
+++ b/code/nel/src/misc/file.cpp
@@ -237,7 +237,9 @@ bool		CIFile::open(const std::string &path, bool text)
 			}
 		}
 	}
-	else
+
+	// not in bnp, but may have '@' in the name
+	if (_F == NULL)
 	{
 		_IsInBigFile = false;
 		_IsInXMLPackFile = false;

From 82f084982a45947cd203b628833f0841ba930092 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Mon, 29 Apr 2019 14:10:19 +0300
Subject: [PATCH 03/75] Fixed: Reusing CIFile to load from bnp and from regular
 files.

--HG--
branch : develop
---
 code/nel/src/misc/file.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/code/nel/src/misc/file.cpp b/code/nel/src/misc/file.cpp
index 7eae0f6a5..63b27e768 100644
--- a/code/nel/src/misc/file.cpp
+++ b/code/nel/src/misc/file.cpp
@@ -157,6 +157,14 @@ bool		CIFile::open(const std::string &path, bool text)
 
 	close();
 
+	if ((_IsInBigFile || _IsInXMLPackFile) && path.find('@') == string::npos)
+	{
+		// CIFile can be reused to load file from bnp and from regular files.
+		// Last open happened to be inside bnp and close() may not set _F to NULL.
+		// Opening regular file will fail as _F points to bnp file.
+		_F = NULL;
+	}
+
 	// can't open empty filename
 	if(path.empty ())
 		return false;

From 7f41881be7b05bddc2a050c860fd845c3831de9e Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Mon, 29 Apr 2019 15:03:32 +0300
Subject: [PATCH 04/75] Changed: Split http parsing from CGroupHTML

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_html.h         |  8 ++-
 code/nel/include/nel/gui/html_parser.h        | 52 +++++++++++++++++++
 code/nel/src/gui/group_html.cpp               | 26 ++++++++++
 ...{group_html_parser.cpp => html_parser.cpp} | 37 +++++--------
 4 files changed, 94 insertions(+), 29 deletions(-)
 create mode 100644 code/nel/include/nel/gui/html_parser.h
 rename code/nel/src/gui/{group_html_parser.cpp => html_parser.cpp} (89%)

diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index 55daa3c52..b21841f8c 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -151,7 +151,7 @@ namespace NLGUI
 		virtual void browse (const char *url);
 
 		// parse html string using libxml2 parser
-		virtual bool parseHtml(std::string htmlString);
+		bool parseHtml(const std::string &htmlString);
 
 		// Refresh
 		void refresh();
@@ -346,10 +346,6 @@ namespace NLGUI
 		// the current request is terminated
 		virtual void requestTerminated();
 
-		// libxml2 html parser functions
-		void htmlElement(xmlNode *node, int element_number);
-		void htmlWalkDOM(xmlNode *a_node);
-
 		// Get Home URL
 		virtual std::string	home();
 
@@ -815,6 +811,8 @@ namespace NLGUI
 		void buildHTTPPostParams (SFormFields &formfields);
 
 	private:
+		friend class CHtmlParser;
+
 		// decode all HTML entities
 		static ucstring decodeHTMLEntities(const ucstring &str);
 		
diff --git a/code/nel/include/nel/gui/html_parser.h b/code/nel/include/nel/gui/html_parser.h
new file mode 100644
index 000000000..132c4ac88
--- /dev/null
+++ b/code/nel/include/nel/gui/html_parser.h
@@ -0,0 +1,52 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef CL_HTML_PARSER_H
+#define CL_HTML_PARSER_H
+
+#include "nel/misc/types_nl.h"
+
+namespace NLGUI
+{
+	class CGroupHTML;
+
+	/**
+	 * \brief HTML parsing
+	 * \date 2019-03-15 10:50 GMT
+	 * \author Meelis Mägi (Nimetu)
+	 */
+	class CHtmlParser
+	{
+	public:
+		CHtmlParser(CGroupHTML *group) : _GroupHtml(group)
+		{}
+
+		bool parseHtml(std::string htmlString);
+
+	private:
+		// libxml2 html parser functions
+		void htmlElement(xmlNode *node, int element_number);
+		void parseNode(xmlNode *a_node);
+
+	private:
+
+		CGroupHTML *_GroupHtml;
+	};
+
+}
+
+#endif
+
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 0bdebf865..36d0eab7f 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -48,6 +48,7 @@
 #include "nel/gui/http_cache.h"
 #include "nel/gui/http_hsts.h"
 #include "nel/gui/curl_certificates.h"
+#include "nel/gui/html_parser.h"
 
 #include <curl/curl.h>
 
@@ -6049,6 +6050,19 @@ namespace NLGUI
 		return true;
 	}
 
+	// ***************************************************************************
+	int CGroupHTML::luaParseHtml(CLuaState &ls)
+	{
+		const char *funcName = "parseHtml";
+		CLuaIHM::checkArgCount(ls, funcName, 1);
+		CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
+		std::string html = ls.toString(1);
+
+		parseHtml(html);
+
+		return 0;
+	}
+
 	int CGroupHTML::luaClearRefresh(CLuaState &ls)
 	{
 		const char *funcName = "clearRefresh";
@@ -6284,6 +6298,18 @@ namespace NLGUI
 		browse(url.c_str());
 	}
 
+	// ***************************************************************************
+	bool CGroupHTML::parseHtml(const std::string &htmlString)
+	{
+		CHtmlParser html(this);
+
+		bool result = html.parseHtml(htmlString);
+		if (result)
+			_DocumentHtml = htmlString;
+
+		return result;
+	}
+
 	// ***************************************************************************
 	inline bool isDigit(ucchar c, uint base = 16)
 	{
diff --git a/code/nel/src/gui/group_html_parser.cpp b/code/nel/src/gui/html_parser.cpp
similarity index 89%
rename from code/nel/src/gui/group_html_parser.cpp
rename to code/nel/src/gui/html_parser.cpp
index 0069fd77d..8470d0524 100644
--- a/code/nel/src/gui/group_html_parser.cpp
+++ b/code/nel/src/gui/html_parser.cpp
@@ -17,13 +17,14 @@
 
 #include "stdpch.h"
 
+#include "nel/gui/html_parser.h"
+
 #include <string>
 #include <libxml/HTMLparser.h>
 
 #include "nel/misc/types_nl.h"
 #include "nel/gui/libwww.h"
 #include "nel/gui/group_html.h"
-#include "nel/gui/lua_ihm.h"
 
 using namespace std;
 using namespace NLMISC;
@@ -35,7 +36,7 @@ using namespace NLMISC;
 namespace NLGUI
 {
 	// ***************************************************************************
-	void CGroupHTML::htmlElement(xmlNode *node, int element_number)
+	void CHtmlParser::htmlElement(xmlNode *node, int element_number)
 	{
 		SGML_dtd *HTML_DTD = HTML_dtd ();
 
@@ -65,30 +66,30 @@ namespace NLGUI
 				}
 			}
 
-			beginElement(element_number, present, value);
+			_GroupHtml->beginElement(element_number, present, value);
 		}
 		else
 		{
-			beginUnparsedElement((const char *)(node->name), xmlStrlen(node->name));
+			_GroupHtml->beginUnparsedElement((const char *)(node->name), xmlStrlen(node->name));
 		}
 
 		// recursive - text content / child nodes
-		htmlWalkDOM(node->children);
+		parseNode(node->children);
 
 		// closing tag
 		if (element_number < HTML_ELEMENTS)
 		{
-			endElement(element_number);
+			_GroupHtml->endElement(element_number);
 		}
 		else
 		{
-			endUnparsedElement((const char *)(node->name), xmlStrlen(node->name));
+			_GroupHtml->endUnparsedElement((const char *)(node->name), xmlStrlen(node->name));
 		}
 	}
 
 	// ***************************************************************************
 	// recursive function to walk html document
-	void CGroupHTML::htmlWalkDOM(xmlNode *a_node)
+	void CHtmlParser::parseNode(xmlNode *a_node)
 	{
 		SGML_dtd *HTML_DTD = HTML_dtd ();
 
@@ -98,7 +99,7 @@ namespace NLGUI
 		{
 			if (node->type == XML_TEXT_NODE)
 			{
-				addText((const char *)(node->content), xmlStrlen(node->content));
+				_GroupHtml->addText((const char *)(node->content), xmlStrlen(node->content));
 			}
 			else
 			if (node->type == XML_ELEMENT_NODE)
@@ -297,7 +298,7 @@ namespace NLGUI
 	}
 
 	// ***************************************************************************
-	bool CGroupHTML::parseHtml(std::string htmlString)
+	bool CHtmlParser::parseHtml(std::string htmlString)
 	{
 		htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, XML_CHAR_ENCODING_UTF8);
 		if (!parser)
@@ -320,7 +321,7 @@ namespace NLGUI
 			xmlNode *root = xmlDocGetRootElement(parser->myDoc);
 			if (root)
 			{
-				htmlWalkDOM(root);
+				parseNode(root);
 			}
 			else
 			{
@@ -339,18 +340,6 @@ namespace NLGUI
 		return success;
 	}
 
-	// ***************************************************************************
-	int CGroupHTML::luaParseHtml(CLuaState &ls)
-	{
-		const char *funcName = "parseHtml";
-		CLuaIHM::checkArgCount(ls, funcName, 1);
-		CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
-		std::string html = ls.toString(1);
-
-		parseHtml(html);
-
-		return 0;
-	}
-
 }
 
+

From c107bdc56f7e88aaf2ee310de29e07ea3008668f Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 29 Mar 2019 15:03:39 +0200
Subject: [PATCH 05/75] Changed: Split css style from CGroupHTML

--HG--
branch : develop
---
 code/nel/include/nel/gui/css_parser.h |   39 +
 code/nel/include/nel/gui/css_style.h  |  141 +++
 code/nel/include/nel/gui/group_html.h |   96 +-
 code/nel/include/nel/gui/libwww.h     |    7 +-
 code/nel/src/gui/css_parser.cpp       |   58 ++
 code/nel/src/gui/css_style.cpp        |  496 ++++++++++
 code/nel/src/gui/group_html.cpp       | 1258 +++++--------------------
 code/nel/src/gui/libwww.cpp           |  362 +++++++
 8 files changed, 1342 insertions(+), 1115 deletions(-)
 create mode 100644 code/nel/include/nel/gui/css_parser.h
 create mode 100644 code/nel/include/nel/gui/css_style.h
 create mode 100644 code/nel/src/gui/css_parser.cpp
 create mode 100644 code/nel/src/gui/css_style.cpp

diff --git a/code/nel/include/nel/gui/css_parser.h b/code/nel/include/nel/gui/css_parser.h
new file mode 100644
index 000000000..cb4cea62e
--- /dev/null
+++ b/code/nel/include/nel/gui/css_parser.h
@@ -0,0 +1,39 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef CL_CSS_PARSER_H
+#define CL_CSS_PARSER_H
+
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_style.h"
+
+namespace NLGUI
+{
+	/**
+	 * \brief CSS style parsing
+	 * \date 2019-03-15 10:50 GMT
+	 * \author Meelis Mägi (Nimetu)
+	 */
+	class CCssParser {
+	public:
+		// parse style declaration, eg "color: red; font-size: 10px;"
+		static TStyle parseDecls(const std::string &styleString);
+	};
+
+}//namespace
+
+#endif // CL_CSS_PARSER_H
+
diff --git a/code/nel/include/nel/gui/css_style.h b/code/nel/include/nel/gui/css_style.h
new file mode 100644
index 000000000..2a854a6d9
--- /dev/null
+++ b/code/nel/include/nel/gui/css_style.h
@@ -0,0 +1,141 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef CL_CSS_STYLE_H
+#define CL_CSS_STYLE_H
+
+#include "nel/misc/types_nl.h"
+#include "nel/misc/rgba.h"
+
+namespace NLGUI
+{
+	typedef std::map<std::string, std::string> TStyle;
+
+	/**
+	 * \brief CSS style rules
+	 * \date 2019-03-15 10:50 GMT
+	 * \author Meelis Mägi (Nimetu)
+	 */
+	class CStyleParams
+	{
+	public:
+		struct STextShadow
+		{
+		public:
+			STextShadow(bool enabled = false, bool outline = false, sint32 x=1, sint32 y=1, NLMISC::CRGBA color=NLMISC::CRGBA::Black)
+				: Enabled(enabled), Outline(outline), X(x), Y(y), Color(color)
+			{ }
+
+			bool Enabled;
+			bool Outline;
+			sint32 X;
+			sint32 Y;
+			NLMISC::CRGBA Color;
+		};
+	public:
+		CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
+		{
+			FontSize=10;
+			FontWeight=400;
+			FontOblique=false;
+			Underlined=false;
+			StrikeThrough=false;
+			GlobalColor=false;
+			Width=-1;
+			Height=-1;
+			MaxWidth=-1;
+			MaxHeight=-1;
+			BorderWidth=1;
+			BackgroundColor=NLMISC::CRGBA::Black;
+			BackgroundColorOver=NLMISC::CRGBA::Black;
+		}
+		uint FontSize;
+		uint FontWeight;
+		bool FontOblique;
+		std::string FontFamily;
+		NLMISC::CRGBA TextColor;
+		STextShadow TextShadow;
+		bool GlobalColor;
+		bool Underlined;
+		bool StrikeThrough;
+		sint32 Width;
+		sint32 Height;
+		sint32 MaxWidth;
+		sint32 MaxHeight;
+		sint32 BorderWidth;
+		NLMISC::CRGBA BackgroundColor;
+		NLMISC::CRGBA BackgroundColorOver;
+	};
+
+	class CCssStyle {
+	public:
+
+
+		// 'browser' style, overwriten with '<html>'
+		CStyleParams Root;
+
+		// current element style
+		CStyleParams Current;
+
+	private:
+		std::vector<CStyleParams> _StyleStack;
+
+		// test if str is one of "thin/medium/thick" and return its pixel value 
+		bool scanCssLength(const std::string& str, uint32 &px) const;
+
+		// read style attribute
+		void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current) const;
+
+	public:
+		void reset();
+
+		inline uint getFontSizeSmaller() const
+		{
+			if (Current.FontSize < 5)
+				return 3;
+			return Current.FontSize-2;
+		}
+
+		inline void pushStyle()
+		{
+			_StyleStack.push_back(Current);
+		}
+
+		inline void popStyle()
+		{
+			if (_StyleStack.empty())
+				Current = Root;
+			else
+			{
+				Current = _StyleStack.back();
+				_StyleStack.pop_back();
+			}
+		}
+
+		// apply style string to this.Root
+		void applyRootStyle(const std::string &styleString);
+
+		// apply style string to this.Current
+		void applyStyle(const std::string &styleString);
+
+		void applyCssMinMax(sint32 &width, sint32 &height, sint32 minw=0, sint32 minh=0, sint32 maxw=0, sint32 maxh=0) const;
+
+	};
+
+}//namespace
+
+#endif // CL_CSS_STYLE_H
+
diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index b21841f8c..d8935f431 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -24,12 +24,11 @@
 #include "nel/gui/ctrl_button.h"
 #include "nel/gui/group_table.h"
 #include "nel/gui/libwww_types.h"
+#include "nel/gui/css_style.h"
 
 // forward declaration
 typedef void CURLM;
 
-typedef std::map<std::string, std::string>	TStyle;
-
 namespace NLGUI
 {
 	class CCtrlButton;
@@ -76,58 +75,6 @@ namespace NLGUI
 
 		static SWebOptions options;
 
-		// text-shadow
-		struct STextShadow
-		{
-		public:
-			STextShadow(bool enabled = false, bool outline = false, sint32 x=1, sint32 y=1, NLMISC::CRGBA color=NLMISC::CRGBA::Black)
-				: Enabled(enabled), Outline(outline), X(x), Y(y), Color(color)
-			{ }
-
-			bool Enabled;
-			bool Outline;
-			sint32 X;
-			sint32 Y;
-			NLMISC::CRGBA Color;
-		};
-
-		class CStyleParams
-		{
-		public:
-			CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
-			{
-				FontSize=10;
-				FontWeight=400;
-				FontOblique=false;
-				Underlined=false;
-				StrikeThrough=false;
-				GlobalColor=false;
-				Width=-1;
-				Height=-1;
-				MaxWidth=-1;
-				MaxHeight=-1;
-				BorderWidth=1;
-				BackgroundColor=NLMISC::CRGBA::Black;
-				BackgroundColorOver=NLMISC::CRGBA::Black;
-			}
-			uint FontSize;
-			uint FontWeight;
-			bool FontOblique;
-			std::string FontFamily;
-			NLMISC::CRGBA TextColor;
-			STextShadow TextShadow;
-			bool GlobalColor;
-			bool Underlined;
-			bool StrikeThrough;
-			sint32 Width;
-			sint32 Height;
-			sint32 MaxWidth;
-			sint32 MaxHeight;
-			sint32 BorderWidth;
-			NLMISC::CRGBA BackgroundColor;
-			NLMISC::CRGBA BackgroundColorOver;
-		};
-
 		// ImageDownload system
 		enum TDataType {ImgType= 0, BnpType};
 		enum TImageType {NormalImage=0, OverImage};
@@ -535,33 +482,8 @@ namespace NLGUI
 		// IL mode
 		bool _LI;
 
-		// Current active style
-		CStyleParams _Style;
-		// Default style
-		CStyleParams _StyleDefault;
-		// Nested style stack
-		std::vector<CStyleParams> _StyleParams;
-		inline void pushStyle()
-		{
-			_StyleParams.push_back(_Style);
-		}
-		inline void popStyle()
-		{
-			if (_StyleParams.empty())
-				_Style = _StyleDefault;
-			else
-			{
-				_Style = _StyleParams.back();
-				_StyleParams.pop_back();
-			}
-		}
-
-		inline uint getFontSizeSmaller() const
-		{
-			if (_Style.FontSize < 5)
-				return 3;
-			return _Style.FontSize-2;
-		}
+		// Keep track of current element style
+		CCssStyle _Style;
 
 		// Current link
 		std::vector<std::string>	_Link;
@@ -625,14 +547,6 @@ namespace NLGUI
 			return _TR.back();
 		}
 
-		std::vector<STextShadow> _TextShadow;
-		inline STextShadow getTextShadow() const
-		{
-			if (_TextShadow.empty())
-				return STextShadow();
-			return _TextShadow.back();
-		}
-
 		// Forms
 		class CForm
 		{
@@ -794,10 +708,6 @@ namespace NLGUI
 		typedef std::map<uint32, NLMISC::CRefPtr<CGroupHTML> >	TGroupHtmlByUIDMap;
 		static TGroupHtmlByUIDMap _GroupHtmlByUID;
 
-		// read style attribute
-		void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current);
-		void applyCssMinMax(sint32 &width, sint32 &height, sint32 minw=0, sint32 minh=0, sint32 maxw=0, sint32 maxh=0);
-
 		// load and render local html file (from bnp for example)
 		void doBrowseLocalFile(const std::string &filename);
 
diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h
index 84eeb01e9..d7fe1251c 100644
--- a/code/nel/include/nel/gui/libwww.h
+++ b/code/nel/include/nel/gui/libwww.h
@@ -276,9 +276,14 @@ namespace NLGUI
 		HTML_ATTR(H6,STYLE),
 	};
 
-
 	#undef HTML_ATTR
 
+	// ***************************************************************************
+	// Read HTML color value from src and set dest
+	// Can handle #rgb(a), #rrggbb(aa) or rgb()/rgba(), hsl(), hsla() formats
+	// or color name directly
+	bool scanHTMLColor(const char *src, NLMISC::CRGBA &dest);
+
 	// ***************************************************************************
 	// Read a CSS length value, return true if one of supported units '%, rem, em, px, pt'
 	// On failure: 'value' and 'unit' values are undefined
diff --git a/code/nel/src/gui/css_parser.cpp b/code/nel/src/gui/css_parser.cpp
new file mode 100644
index 000000000..c45121824
--- /dev/null
+++ b/code/nel/src/gui/css_parser.cpp
@@ -0,0 +1,58 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "stdpch.h"
+
+#include <string>
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_parser.h"
+#include "nel/gui/css_style.h"
+
+using namespace NLMISC;
+
+#ifdef DEBUG_NEW
+#define new DEBUG_NEW
+#endif
+
+namespace NLGUI
+{
+	// ***************************************************************************
+	// Parse style declarations style, eg. "color:red; font-size: 10px;"
+	//
+	// key is converted to lowercase
+	// value is left as is
+	TStyle CCssParser::parseDecls(const std::string &styleString)
+	{
+		TStyle styles;
+		std::vector<std::string> elements;
+		NLMISC::splitString(styleString, ";", elements);
+
+		for(uint i = 0; i < elements.size(); ++i)
+		{
+			std::string::size_type pos;
+			pos = elements[i].find_first_of(':');
+			if (pos != std::string::npos)
+			{
+				std::string key = trim(toLower(elements[i].substr(0, pos)));
+				std::string value = trim(elements[i].substr(pos+1));
+				styles[key] = value;
+			}
+		}
+
+		return styles;
+	}
+} // namespace
+
diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp
new file mode 100644
index 000000000..9d4b665bb
--- /dev/null
+++ b/code/nel/src/gui/css_style.cpp
@@ -0,0 +1,496 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "stdpch.h"
+
+#include <string>
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_style.h"
+#include "nel/gui/css_parser.h"
+#include "nel/gui/libwww.h"
+
+using namespace NLMISC;
+
+#ifdef DEBUG_NEW
+#define new DEBUG_NEW
+#endif
+
+namespace NLGUI
+{
+	// ***************************************************************************
+	void CCssStyle::reset()
+	{
+		_StyleStack.clear();
+
+		Root = CStyleParams();
+		Current = CStyleParams();
+	}
+
+	// ***************************************************************************
+	void CCssStyle::applyRootStyle(const std::string &styleString)
+	{
+		getStyleParams(styleString, Root, Root);
+	}
+
+	// ***************************************************************************
+	void CCssStyle::applyStyle(const std::string &styleString)
+	{
+		if (_StyleStack.empty())
+		{
+			getStyleParams(styleString, Current, Root);
+		}
+		else
+		{
+			getStyleParams(styleString, Current, _StyleStack.back());
+		}
+	}
+
+	bool CCssStyle::scanCssLength(const std::string& str, uint32 &px) const
+	{
+		if (fromString(str, px))
+			return true;
+
+		if (str == "thin")
+		{
+			px = 1;
+			return true;
+		}
+		if (str == "medium")
+		{
+			px = 3;
+			return true;
+		}
+		if (str == "thick")
+		{
+			px = 5;
+			return true;
+		}
+
+		return false;
+	}
+
+	// ***************************************************************************
+	// CStyleParams style;
+	// style.FontSize;    // font-size: 10px;
+	// style.TextColor;   // color: #ABCDEF;
+	// style.Underlined;  // text-decoration: underline;     text-decoration-line: underline;
+	// style.StrikeThrough; // text-decoration: line-through;  text-decoration-line: line-through;
+	void CCssStyle::getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current) const
+	{
+		float tmpf;
+		TStyle styles = CCssParser::parseDecls(styleString);
+		TStyle::iterator it;
+
+		// first pass: get font-size for 'em' sizes
+		for (it=styles.begin(); it != styles.end(); ++it)
+		{
+			if (it->first == "font")
+			{
+				if (it->second == "inherit")
+				{
+					style.FontSize = current.FontSize;
+					style.FontFamily = current.FontFamily;
+					style.FontWeight = current.FontWeight;
+					style.FontOblique = current.FontOblique;
+				}
+			}
+			else
+			if (it->first == "font-size")
+			{
+				if (it->second == "inherit")
+				{
+					style.FontSize = current.FontSize;
+				}
+				else
+				{
+					std::string unit;
+					if (getCssLength(tmpf, unit, it->second.c_str()))
+					{
+						if (unit == "rem")
+							style.FontSize = Root.FontSize * tmpf;
+						else if (unit == "em")
+							style.FontSize = current.FontSize * tmpf;
+						else if (unit == "pt")
+							style.FontSize = tmpf / 0.75f;
+						else if (unit == "%")
+							style.FontSize = current.FontSize * tmpf / 100.f;
+						else
+							style.FontSize = tmpf;
+					}
+				}
+			}
+		}
+
+		// second pass: rest of style
+		for (it=styles.begin(); it != styles.end(); ++it)
+		{
+			if (it->first == "border")
+			{
+				sint32 b;
+				if (it->second == "none")
+					style.BorderWidth = 0;
+				else
+				if (fromString(it->second, b))
+					style.BorderWidth = b;
+			}
+			else
+			if (it->first == "font-style")
+			{
+				if (it->second == "inherit")
+					style.FontOblique = current.FontOblique;
+				else
+				if (it->second == "italic" || it->second == "oblique")
+					style.FontOblique = true;
+			}
+			else
+			if (it->first == "font-family")
+			{
+				if (it->second == "inherit")
+					style.FontFamily = current.FontFamily;
+				else
+					style.FontFamily = it->second;
+			}
+			else
+			if (it->first == "font-weight")
+			{
+				// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
+				uint weight = 400;
+				if (it->second == "inherit")
+					weight = current.FontWeight;
+				else
+				if (it->second == "normal")
+					weight = 400;
+				else
+				if (it->second == "bold")
+					weight = 700;
+				else
+				if (it->second == "lighter")
+				{
+					const uint lighter[] = {100, 100, 100, 100, 100, 400, 400, 700, 700};
+					uint index = current.FontWeight / 100 - 1;
+					clamp(index, 1u, 9u);
+					weight = lighter[index-1];
+				}
+				else
+				if (it->second == "bolder")
+				{
+					const uint bolder[] =  {400, 400, 400, 700, 700, 900, 900, 900, 900};
+					uint index = current.FontWeight / 100 + 1;
+					clamp(index, 1u, 9u);
+					weight = bolder[index-1];
+				}
+				else
+				if (fromString(it->second, weight))
+				{
+					weight = (weight / 100);
+					clamp(weight, 1u, 9u);
+					weight *= 100;
+				}
+				style.FontWeight = weight;
+			}
+			else
+			if (it->first == "color")
+				if (it->second == "inherit")
+					style.TextColor = current.TextColor;
+				else
+					scanHTMLColor(it->second.c_str(), style.TextColor);
+			else
+			if (it->first == "text-decoration" || it->first == "text-decoration-line")
+			{
+				std::string prop(toLower(it->second));
+				style.Underlined = (prop.find("underline") != std::string::npos);
+				style.StrikeThrough = (prop.find("line-through") != std::string::npos);
+			}
+			else
+			if (it->first == "text-stroke" || it->first == "-webkit-text-stroke")
+			{
+				// text-stroke: length || color
+				bool success = false;
+				uint px = 0;
+				CRGBA color;
+				std::vector<std::string> parts;
+				NLMISC::splitString(it->second, " ", parts);
+				if (parts.size() == 1)
+				{
+					success = scanCssLength(parts[0], px);
+					if (!success)
+						success = scanHTMLColor(parts[0].c_str(), color);
+				}
+				else if (parts.size() == 2)
+				{
+					success = scanCssLength(parts[0], px);
+					if (success)
+						success = scanHTMLColor(parts[1].c_str(), color);
+					else
+					{
+						success = scanHTMLColor(parts[0].c_str(), color);
+						success = success && scanCssLength(parts[1], px);
+					}
+				}
+
+				// do not disable shadow if one is already set
+				if (success)
+				{
+					style.TextShadow.Enabled = (px > 0);
+					style.TextShadow.Color = color;
+					style.TextShadow.X = px;
+					style.TextShadow.Y = px;
+					style.TextShadow.Outline = true;
+				}
+			}
+			else
+			if (it->first == "text-shadow")
+			{
+				if (it->second == "none")
+					style.TextShadow = CStyleParams::STextShadow(false);
+				else
+				if (it->second == "inherit")
+					style.TextShadow = current.TextShadow;
+				else
+				{
+					// text-shadow: offset-x offset-y | blur | #color
+					// text-shadow: #color | offset-x offset-y
+					bool success = true;
+					std::string prop(it->second);
+					size_t pos;
+					pos = prop.find_first_of(",\n\r");
+					if (pos != std::string::npos)
+						prop = prop.substr(0, pos);
+
+					std::vector<std::string> parts;
+					NLMISC::splitString(prop, " ", parts);
+					switch(parts.size())
+					{
+						case 1:
+						{
+							success = scanHTMLColor(it->second.c_str(), style.TextShadow.Color);
+							break;
+						}
+						// no case 2:
+						case 3:
+						{
+							if (!fromString(parts[0], style.TextShadow.X))
+							{
+								success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
+								success = success && fromString(parts[1], style.TextShadow.X);
+								success = success && fromString(parts[2], style.TextShadow.Y);
+							}
+							else
+							{
+								success = fromString(parts[1], style.TextShadow.Y);
+								success = success && scanHTMLColor(parts[2].c_str(), style.TextShadow.Color);
+							}
+							break;
+						}
+						case 4:
+						{
+							if (!fromString(parts[0], style.TextShadow.X))
+							{
+								success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
+								success = success && fromString(parts[1], style.TextShadow.X);
+								success = success && fromString(parts[2], style.TextShadow.Y);
+								// ignore blur [3]
+							}
+							else
+							{
+								success = fromString(parts[0], style.TextShadow.X);
+								success = success && fromString(parts[1], style.TextShadow.Y);
+								// ignore blur [2]
+								success = success && scanHTMLColor(parts[3].c_str(), style.TextShadow.Color);
+							}
+							break;
+						}
+						default:
+						{
+							// unsupported rule
+							break;
+						}
+					}
+
+					style.TextShadow.Enabled = success;
+				}
+			}
+			else
+			if (it->first == "width")
+			{
+				std::string unit;
+				if (getCssLength(tmpf, unit, it->second.c_str()))
+				{
+					if (unit == "rem")
+						style.Width = tmpf * Root.FontSize;
+					else if (unit == "em")
+						style.Width = tmpf * style.FontSize;
+					else if (unit == "pt")
+						style.FontSize = tmpf / 0.75f;
+					else
+						style.Width = tmpf;
+				}
+			}
+			else
+			if (it->first == "height")
+			{
+				std::string unit;
+				if (getCssLength(tmpf, unit, it->second.c_str()))
+				{
+					if (unit == "rem")
+						style.Height = tmpf * Root.FontSize;
+					else if (unit == "em")
+						style.Height = tmpf * style.FontSize;
+					else if (unit == "pt")
+						style.FontSize = tmpf / 0.75f;
+					else
+						style.Height = tmpf;
+				}
+			}
+			else
+			if (it->first == "max-width")
+			{
+				std::string unit;
+				if (getCssLength(tmpf, unit, it->second.c_str()))
+				{
+					if (unit == "rem")
+						style.MaxWidth = tmpf * Root.FontSize;
+					else if (unit == "em")
+						style.MaxWidth = tmpf * style.FontSize;
+					else if (unit == "pt")
+						style.FontSize = tmpf / 0.75f;
+					else
+						style.MaxWidth = tmpf;
+				}
+			}
+			else
+			if (it->first == "max-height")
+			{
+				std::string unit;
+				if (getCssLength(tmpf, unit, it->second.c_str()))
+				{
+					if (unit == "rem")
+						style.MaxHeight = tmpf * Root.FontSize;
+					else if (unit == "em")
+						style.MaxHeight = tmpf * style.FontSize;
+					else if (unit == "pt")
+						style.FontSize = tmpf / 0.75f;
+					else
+						style.MaxHeight = tmpf;
+				}
+			}
+			else
+			if (it->first == "-ryzom-modulate-color")
+			{
+				bool b;
+				if (it->second == "inherit")
+					style.GlobalColor = current.GlobalColor;
+				else
+				if (fromString(it->second, b))
+					style.GlobalColor = b;
+			}
+			else
+			if (it->first == "background-color")
+			{
+				if (it->second == "inherit")
+					style.BackgroundColor = current.BackgroundColor;
+				else
+					scanHTMLColor(it->second.c_str(), style.BackgroundColor);
+			}
+			else
+			if (it->first == "-ryzom-background-color-over")
+			{
+				if (it->second == "inherit")
+					style.BackgroundColorOver = current.BackgroundColorOver;
+				else
+					scanHTMLColor(it->second.c_str(), style.BackgroundColorOver);
+			}
+		}
+
+		// if outer element has underline set, then inner element cannot remove it
+		if (current.Underlined)
+			style.Underlined = current.Underlined;
+
+		// if outer element has line-through set, then inner element cannot remove it
+		if (current.StrikeThrough)
+			style.StrikeThrough = current.StrikeThrough;
+	}
+
+	// ***************************************************************************
+	void CCssStyle::applyCssMinMax(sint32 &width, sint32 &height, sint32 minw, sint32 minh, sint32 maxw, sint32 maxh) const
+	{
+		if (maxw <= 0) maxw = width;
+		if (maxh <= 0) maxh = height;
+
+		maxw = std::max(minw, maxw);
+		maxh = std::max(minh, maxh);
+
+		float ratio = (float) width / std::max(1, height);
+		if (width > maxw)
+		{
+			width = maxw;
+			height = std::max((sint32)(maxw /ratio), minh);
+		}
+		if (width < minw)
+		{
+			width = minw;
+			height = std::min((sint32)(minw / ratio), maxh);
+		}
+		if (height > maxh)
+		{
+			width = std::max((sint32)(maxh * ratio), minw);
+			height = maxh;
+		}
+		if (height < minh)
+		{
+			width = std::min((sint32)(minh * ratio), maxw);
+			height = minh;
+		}
+		if (width > maxw && height > maxh)
+		{
+			if (maxw/width <= maxh/height)
+			{
+				width = maxw;
+				height = std::max(minh, (sint32)(maxw / ratio));
+			}
+			else
+			{
+				width = std::max(minw, (sint32)(maxh * ratio));
+				height = maxh;
+			}
+		}
+		if (width < minw && height < minh)
+		{
+			if (minw / width <= minh / height)
+			{
+				width = std::min(maxw, (sint32)(minh * ratio));
+				height = minh;
+			}
+			else
+			{
+				width = minw;
+				height = std::min(maxh, (sint32)(minw / ratio));
+			}
+		}
+		if (width < minw && height > maxh)
+		{
+			width = minw;
+			height = maxh;
+		}
+		if (width > maxw && height < minh)
+		{
+			width = maxw;
+			height = minh;
+		}
+	}
+
+} // namespace
+
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 36d0eab7f..ba21c6af1 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -357,7 +357,7 @@ namespace NLGUI
 		// apply max-width, max-height rules if asked
 		if (maxw > -1 || maxh > -1)
 		{
-			applyCssMinMax(width, height, 0, 0, maxw, maxh);
+			_Style.applyCssMinMax(width, height, 0, 0, maxw, maxh);
 			changed = true;
 		}
 
@@ -386,29 +386,33 @@ namespace NLGUI
 	void CGroupHTML::setTextButtonStyle(CCtrlTextButton *ctrlButton, const CStyleParams &style)
 	{
 		// this will also set size for <a class="ryzom-ui-button"> treating it like "display: inline-block;"
-		if (style.Width > 0)  ctrlButton->setWMin(_Style.Width);
-		if (style.Height > 0) ctrlButton->setHMin(_Style.Height);
+		if (style.Width > 0)  ctrlButton->setWMin(style.Width);
+		if (style.Height > 0) ctrlButton->setHMin(style.Height);
 
 		CViewText *pVT = ctrlButton->getViewText();
 		if (pVT)
 		{
-			setTextStyle(pVT, _Style);
+			setTextStyle(pVT, style);
 		}
 
-		if (_Style.BackgroundColor.A > 0)
+		if (style.BackgroundColor.A > 0)
 		{
-			if (_Style.BackgroundColorOver.A == 0)
-				_Style.BackgroundColorOver = _Style.BackgroundColor;
-
-			ctrlButton->setColor(_Style.BackgroundColor);
-			ctrlButton->setColorOver(_Style.BackgroundColorOver);
+			ctrlButton->setColor(style.BackgroundColor);
+			if (style.BackgroundColorOver.A == 0)
+			{
+				ctrlButton->setColorOver(style.BackgroundColor);
+			}
+			else
+			{
+				ctrlButton->setColorOver(style.BackgroundColorOver);
+			}
 			ctrlButton->setTexture("", "blank.tga", "", false);
 			ctrlButton->setTextureOver("", "blank.tga", "");
 			ctrlButton->setProperty("force_text_over", "true");
 		}
-		else if (_Style.BackgroundColorOver.A > 0)
+		else if (style.BackgroundColorOver.A > 0)
 		{
-			ctrlButton->setColorOver(_Style.BackgroundColorOver);
+			ctrlButton->setColorOver(style.BackgroundColorOver);
 			ctrlButton->setProperty("force_text_over", "true");
 			ctrlButton->setTextureOver("blank.tga", "blank.tga", "blank.tga");
 		}
@@ -1027,7 +1031,7 @@ namespace NLGUI
 
 	TStyle CGroupHTML::parseStyle (const string &str_styles)
 	{
-		TStyle	styles;
+		TStyle styles;
 		vector<string> elements;
 		NLMISC::splitString(str_styles, ";", elements);
 
@@ -1149,392 +1153,6 @@ namespace NLGUI
 		_CellParams.push_back (cellParams); \
 	}
 
-	static bool scanCssLength(const std::string& str, uint32 &px)
-	{
-		if (fromString(str, px))
-			return true;
-
-		if (str == "thin")
-		{
-			px = 1;
-			return true;
-		}
-		if (str == "medium")
-		{
-			px = 3;
-			return true;
-		}
-		if (str == "thick")
-		{
-			px = 5;
-			return true;
-		}
-
-		return false;
-	}
-
-	static bool isHexa(char c)
-	{
-		return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f');
-	}
-
-	static uint8 convertHexa(char c)
-	{
-		return (uint8) (tolower(c) - (isdigit(c) ? '0' : ('a' - 10)));
-	}
-
-	// scan a color component, and return pointer to next position
-	static const char *scanColorComponent(const char *src, uint8 &intensity)
-	{
-		if (!src) return NULL;
-		if (!isHexa(*src)) return NULL;
-		uint8 value = convertHexa(*src++) << 4;
-		if (!isHexa(*src)) return NULL;
-		value += convertHexa(*src++);
-		intensity = value;
-		return src;
-	}
-
-	static float hueToRgb(float m1, float m2, float h)
-	{
-		if (h < 0) h += 1.0f;
-		if (h > 1) h -= 1.0f;
-		if (h*6 < 1.0f) return m1 + (m2 - m1)*h*6;
-		if (h*2 < 1.0f) return m2;
-		if (h*3 < 2.0f) return m1 + (m2 - m1) * (2.0f/3.0f - h)*6;
-		return m1;
-	}
-
-	static void hslToRgb(float h, float s, float l, CRGBA &result)
-	{
-		float m1, m2;
-		if (l <= 0.5f)
-			m2 = l * (s + 1.0f);
-		else
-			m2 = l + s - l * s;
-		m1 = l*2 - m2;
-
-		result.R = 255 * hueToRgb(m1, m2, h + 1.0f/3.0f);
-		result.G = 255 * hueToRgb(m1, m2, h);
-		result.B = 255 * hueToRgb(m1, m2, h - 1.0f/3.0f);
-		result.A = 255;
-	}
-
-	class CNameToCol
-	{
-	public:
-		const char *Name;
-		CRGBA Color;
-		CNameToCol(const char *name, CRGBA color) : Name(name), Color(color) {}
-	};
-
-	static CNameToCol htmlColorNameToRGBA[] =
-	{
-		CNameToCol("AliceBlue", CRGBA(0xF0, 0xF8, 0xFF)),
-		CNameToCol("AntiqueWhite", CRGBA(0xFA, 0xEB, 0xD7)),
-		CNameToCol("Aqua", CRGBA(0x00, 0xFF, 0xFF)),
-		CNameToCol("Aquamarine", CRGBA(0x7F, 0xFF, 0xD4)),
-		CNameToCol("Azure", CRGBA(0xF0, 0xFF, 0xFF)),
-		CNameToCol("Beige", CRGBA(0xF5, 0xF5, 0xDC)),
-		CNameToCol("Bisque", CRGBA(0xFF, 0xE4, 0xC4)),
-		CNameToCol("Black", CRGBA(0x00, 0x00, 0x00)),
-		CNameToCol("BlanchedAlmond", CRGBA(0xFF, 0xEB, 0xCD)),
-		CNameToCol("Blue", CRGBA(0x00, 0x00, 0xFF)),
-		CNameToCol("BlueViolet", CRGBA(0x8A, 0x2B, 0xE2)),
-		CNameToCol("Brown", CRGBA(0xA5, 0x2A, 0x2A)),
-		CNameToCol("BurlyWood", CRGBA(0xDE, 0xB8, 0x87)),
-		CNameToCol("CadetBlue", CRGBA(0x5F, 0x9E, 0xA0)),
-		CNameToCol("Chartreuse", CRGBA(0x7F, 0xFF, 0x00)),
-		CNameToCol("Chocolate", CRGBA(0xD2, 0x69, 0x1E)),
-		CNameToCol("Coral", CRGBA(0xFF, 0x7F, 0x50)),
-		CNameToCol("CornflowerBlue", CRGBA(0x64, 0x95, 0xED)),
-		CNameToCol("Cornsilk", CRGBA(0xFF, 0xF8, 0xDC)),
-		CNameToCol("Crimson", CRGBA(0xDC, 0x14, 0x3C)),
-		CNameToCol("Cyan", CRGBA(0x00, 0xFF, 0xFF)),
-		CNameToCol("DarkBlue", CRGBA(0x00, 0x00, 0x8B)),
-		CNameToCol("DarkCyan", CRGBA(0x00, 0x8B, 0x8B)),
-		CNameToCol("DarkGoldenRod", CRGBA(0xB8, 0x86, 0x0B)),
-		CNameToCol("DarkGray", CRGBA(0xA9, 0xA9, 0xA9)),
-		CNameToCol("DarkGreen", CRGBA(0x00, 0x64, 0x00)),
-		CNameToCol("DarkKhaki", CRGBA(0xBD, 0xB7, 0x6B)),
-		CNameToCol("DarkMagenta", CRGBA(0x8B, 0x00, 0x8B)),
-		CNameToCol("DarkOliveGreen", CRGBA(0x55, 0x6B, 0x2F)),
-		CNameToCol("Darkorange", CRGBA(0xFF, 0x8C, 0x00)),
-		CNameToCol("DarkOrchid", CRGBA(0x99, 0x32, 0xCC)),
-		CNameToCol("DarkRed", CRGBA(0x8B, 0x00, 0x00)),
-		CNameToCol("DarkSalmon", CRGBA(0xE9, 0x96, 0x7A)),
-		CNameToCol("DarkSeaGreen", CRGBA(0x8F, 0xBC, 0x8F)),
-		CNameToCol("DarkSlateBlue", CRGBA(0x48, 0x3D, 0x8B)),
-		CNameToCol("DarkSlateGray", CRGBA(0x2F, 0x4F, 0x4F)),
-		CNameToCol("DarkTurquoise", CRGBA(0x00, 0xCE, 0xD1)),
-		CNameToCol("DarkViolet", CRGBA(0x94, 0x00, 0xD3)),
-		CNameToCol("DeepPink", CRGBA(0xFF, 0x14, 0x93)),
-		CNameToCol("DeepSkyBlue", CRGBA(0x00, 0xBF, 0xFF)),
-		CNameToCol("DimGray", CRGBA(0x69, 0x69, 0x69)),
-		CNameToCol("DodgerBlue", CRGBA(0x1E, 0x90, 0xFF)),
-		CNameToCol("Feldspar", CRGBA(0xD1, 0x92, 0x75)),
-		CNameToCol("FireBrick", CRGBA(0xB2, 0x22, 0x22)),
-		CNameToCol("FloralWhite", CRGBA(0xFF, 0xFA, 0xF0)),
-		CNameToCol("ForestGreen", CRGBA(0x22, 0x8B, 0x22)),
-		CNameToCol("Fuchsia", CRGBA(0xFF, 0x00, 0xFF)),
-		CNameToCol("Gainsboro", CRGBA(0xDC, 0xDC, 0xDC)),
-		CNameToCol("GhostWhite", CRGBA(0xF8, 0xF8, 0xFF)),
-		CNameToCol("Gold", CRGBA(0xFF, 0xD7, 0x00)),
-		CNameToCol("GoldenRod", CRGBA(0xDA, 0xA5, 0x20)),
-		CNameToCol("Gray", CRGBA(0x80, 0x80, 0x80)),
-		CNameToCol("Green", CRGBA(0x00, 0x80, 0x00)),
-		CNameToCol("GreenYellow", CRGBA(0xAD, 0xFF, 0x2F)),
-		CNameToCol("HoneyDew", CRGBA(0xF0, 0xFF, 0xF0)),
-		CNameToCol("HotPink", CRGBA(0xFF, 0x69, 0xB4)),
-		CNameToCol("IndianRed ", CRGBA(0xCD, 0x5C, 0x5C)),
-		CNameToCol("Indigo  ", CRGBA(0x4B, 0x00, 0x82)),
-		CNameToCol("Ivory", CRGBA(0xFF, 0xFF, 0xF0)),
-		CNameToCol("Khaki", CRGBA(0xF0, 0xE6, 0x8C)),
-		CNameToCol("Lavender", CRGBA(0xE6, 0xE6, 0xFA)),
-		CNameToCol("LavenderBlush", CRGBA(0xFF, 0xF0, 0xF5)),
-		CNameToCol("LawnGreen", CRGBA(0x7C, 0xFC, 0x00)),
-		CNameToCol("LemonChiffon", CRGBA(0xFF, 0xFA, 0xCD)),
-		CNameToCol("LightBlue", CRGBA(0xAD, 0xD8, 0xE6)),
-		CNameToCol("LightCoral", CRGBA(0xF0, 0x80, 0x80)),
-		CNameToCol("LightCyan", CRGBA(0xE0, 0xFF, 0xFF)),
-		CNameToCol("LightGoldenRodYellow", CRGBA(0xFA, 0xFA, 0xD2)),
-		CNameToCol("LightGrey", CRGBA(0xD3, 0xD3, 0xD3)),
-		CNameToCol("LightGreen", CRGBA(0x90, 0xEE, 0x90)),
-		CNameToCol("LightPink", CRGBA(0xFF, 0xB6, 0xC1)),
-		CNameToCol("LightSalmon", CRGBA(0xFF, 0xA0, 0x7A)),
-		CNameToCol("LightSeaGreen", CRGBA(0x20, 0xB2, 0xAA)),
-		CNameToCol("LightSkyBlue", CRGBA(0x87, 0xCE, 0xFA)),
-		CNameToCol("LightSlateBlue", CRGBA(0x84, 0x70, 0xFF)),
-		CNameToCol("LightSlateGray", CRGBA(0x77, 0x88, 0x99)),
-		CNameToCol("LightSteelBlue", CRGBA(0xB0, 0xC4, 0xDE)),
-		CNameToCol("LightYellow", CRGBA(0xFF, 0xFF, 0xE0)),
-		CNameToCol("Lime", CRGBA(0x00, 0xFF, 0x00)),
-		CNameToCol("LimeGreen", CRGBA(0x32, 0xCD, 0x32)),
-		CNameToCol("Linen", CRGBA(0xFA, 0xF0, 0xE6)),
-		CNameToCol("Magenta", CRGBA(0xFF, 0x00, 0xFF)),
-		CNameToCol("Maroon", CRGBA(0x80, 0x00, 0x00)),
-		CNameToCol("MediumAquaMarine", CRGBA(0x66, 0xCD, 0xAA)),
-		CNameToCol("MediumBlue", CRGBA(0x00, 0x00, 0xCD)),
-		CNameToCol("MediumOrchid", CRGBA(0xBA, 0x55, 0xD3)),
-		CNameToCol("MediumPurple", CRGBA(0x93, 0x70, 0xD8)),
-		CNameToCol("MediumSeaGreen", CRGBA(0x3C, 0xB3, 0x71)),
-		CNameToCol("MediumSlateBlue", CRGBA(0x7B, 0x68, 0xEE)),
-		CNameToCol("MediumSpringGreen", CRGBA(0x00, 0xFA, 0x9A)),
-		CNameToCol("MediumTurquoise", CRGBA(0x48, 0xD1, 0xCC)),
-		CNameToCol("MediumVioletRed", CRGBA(0xC7, 0x15, 0x85)),
-		CNameToCol("MidnightBlue", CRGBA(0x19, 0x19, 0x70)),
-		CNameToCol("MintCream", CRGBA(0xF5, 0xFF, 0xFA)),
-		CNameToCol("MistyRose", CRGBA(0xFF, 0xE4, 0xE1)),
-		CNameToCol("Moccasin", CRGBA(0xFF, 0xE4, 0xB5)),
-		CNameToCol("NavajoWhite", CRGBA(0xFF, 0xDE, 0xAD)),
-		CNameToCol("Navy", CRGBA(0x00, 0x00, 0x80)),
-		CNameToCol("OldLace", CRGBA(0xFD, 0xF5, 0xE6)),
-		CNameToCol("Olive", CRGBA(0x80, 0x80, 0x00)),
-		CNameToCol("OliveDrab", CRGBA(0x6B, 0x8E, 0x23)),
-		CNameToCol("Orange", CRGBA(0xFF, 0xA5, 0x00)),
-		CNameToCol("OrangeRed", CRGBA(0xFF, 0x45, 0x00)),
-		CNameToCol("Orchid", CRGBA(0xDA, 0x70, 0xD6)),
-		CNameToCol("PaleGoldenRod", CRGBA(0xEE, 0xE8, 0xAA)),
-		CNameToCol("PaleGreen", CRGBA(0x98, 0xFB, 0x98)),
-		CNameToCol("PaleTurquoise", CRGBA(0xAF, 0xEE, 0xEE)),
-		CNameToCol("PaleVioletRed", CRGBA(0xD8, 0x70, 0x93)),
-		CNameToCol("PapayaWhip", CRGBA(0xFF, 0xEF, 0xD5)),
-		CNameToCol("PeachPuff", CRGBA(0xFF, 0xDA, 0xB9)),
-		CNameToCol("Peru", CRGBA(0xCD, 0x85, 0x3F)),
-		CNameToCol("Pink", CRGBA(0xFF, 0xC0, 0xCB)),
-		CNameToCol("Plum", CRGBA(0xDD, 0xA0, 0xDD)),
-		CNameToCol("PowderBlue", CRGBA(0xB0, 0xE0, 0xE6)),
-		CNameToCol("Purple", CRGBA(0x80, 0x00, 0x80)),
-		CNameToCol("Red", CRGBA(0xFF, 0x00, 0x00)),
-		CNameToCol("RosyBrown", CRGBA(0xBC, 0x8F, 0x8F)),
-		CNameToCol("RoyalBlue", CRGBA(0x41, 0x69, 0xE1)),
-		CNameToCol("SaddleBrown", CRGBA(0x8B, 0x45, 0x13)),
-		CNameToCol("Salmon", CRGBA(0xFA, 0x80, 0x72)),
-		CNameToCol("SandyBrown", CRGBA(0xF4, 0xA4, 0x60)),
-		CNameToCol("SeaGreen", CRGBA(0x2E, 0x8B, 0x57)),
-		CNameToCol("SeaShell", CRGBA(0xFF, 0xF5, 0xEE)),
-		CNameToCol("Sienna", CRGBA(0xA0, 0x52, 0x2D)),
-		CNameToCol("Silver", CRGBA(0xC0, 0xC0, 0xC0)),
-		CNameToCol("SkyBlue", CRGBA(0x87, 0xCE, 0xEB)),
-		CNameToCol("SlateBlue", CRGBA(0x6A, 0x5A, 0xCD)),
-		CNameToCol("SlateGray", CRGBA(0x70, 0x80, 0x90)),
-		CNameToCol("Snow", CRGBA(0xFF, 0xFA, 0xFA)),
-		CNameToCol("SpringGreen", CRGBA(0x00, 0xFF, 0x7F)),
-		CNameToCol("SteelBlue", CRGBA(0x46, 0x82, 0xB4)),
-		CNameToCol("Tan", CRGBA(0xD2, 0xB4, 0x8C)),
-		CNameToCol("Teal", CRGBA(0x00, 0x80, 0x80)),
-		CNameToCol("Thistle", CRGBA(0xD8, 0xBF, 0xD8)),
-		CNameToCol("Tomato", CRGBA(0xFF, 0x63, 0x47)),
-		CNameToCol("Turquoise", CRGBA(0x40, 0xE0, 0xD0)),
-		CNameToCol("Violet", CRGBA(0xEE, 0x82, 0xEE)),
-		CNameToCol("VioletRed", CRGBA(0xD0, 0x20, 0x90)),
-		CNameToCol("Wheat", CRGBA(0xF5, 0xDE, 0xB3)),
-		CNameToCol("White", CRGBA(0xFF, 0xFF, 0xFF)),
-		CNameToCol("WhiteSmoke", CRGBA(0xF5, 0xF5, 0xF5)),
-		CNameToCol("Yellow", CRGBA(0xFF, 0xFF, 0x00)),
-		CNameToCol("YellowGreen", CRGBA(0x9A, 0xCD, 0x32))
-	};
-
-	// scan a color from a HTML form (#rrggbb format)
-	bool scanHTMLColor(const char *src, CRGBA &dest)
-	{
-		if (!src || *src == '\0') return false;
-		if (*src == '#')
-		{
-			++src;
-			if (strlen(src) == 3 || strlen(src) == 4)
-			{
-				bool hasAlpha = (strlen(src) == 4);
-				// check RGB for valid hex
-				if (isHexa(src[0]) && isHexa(src[1]) && isHexa(src[2]))
-				{
-					// check optional A for valid hex
-					if (hasAlpha && !isHexa(src[3])) return false;
-
-					dest.R = convertHexa(src[0]);
-					dest.G = convertHexa(src[1]);
-					dest.B = convertHexa(src[2]);
-
-					dest.R = dest.R << 4 | dest.R;
-					dest.G = dest.G << 4 | dest.G;
-					dest.B = dest.B << 4 | dest.B;
-
-					if (hasAlpha)
-					{
-						dest.A = convertHexa(src[3]);
-						dest.A = dest.A << 4 | dest.A;
-					}
-					else
-						dest.A = 255;
-
-					return true;
-				}
-
-				return false;
-			}
-
-			CRGBA result;
-			src = scanColorComponent(src, result.R); if (!src) return false;
-			src = scanColorComponent(src, result.G); if (!src) return false;
-			src = scanColorComponent(src, result.B); if (!src) return false;
-			src = scanColorComponent(src, result.A);
-			if (!src)
-			{
-				// Alpha is optional
-				result.A = 255;
-			}
-			dest = result;
-			return true;
-		}
-
-		if (strnicmp(src, "rgb(", 4) == 0 || strnicmp(src, "rgba(", 5) == 0)
-		{
-			src += 4;
-			if (*src == '(') src++;
-
-			vector<string> parts;
-			NLMISC::splitString(src, ",", parts);
-			if (parts.size() >= 3)
-			{
-				CRGBA result;
-				sint tmpv;
-				float tmpf;
-
-				// R
-				if (getPercentage(tmpv, tmpf, parts[0].c_str())) tmpv = 255 * tmpf;
-				clamp(tmpv, 0, 255);
-				result.R = tmpv;
-
-				// G
-				if (getPercentage(tmpv, tmpf, parts[1].c_str())) tmpv = 255 * tmpf;
-				clamp(tmpv, 0, 255);
-				result.G = tmpv;
-
-				// B
-				if (getPercentage(tmpv, tmpf, parts[2].c_str())) tmpv = 255 * tmpf;
-				clamp(tmpv, 0, 255);
-				result.B = tmpv;
-
-				// A
-				if (parts.size() == 4)
-				{
-					if (!fromString(parts[3], tmpf)) return false;
-					if (parts[3].find_first_of("%") != std::string::npos)
-						tmpf /= 100;
-
-					tmpv = 255 * tmpf;
-					clamp(tmpv, 0, 255);
-					result.A = tmpv;
-				}
-				else
-					result.A = 255;
-
-				dest = result;
-				return true;
-			}
-
-			return false;
-		}
-
-		if (strnicmp(src, "hsl(", 4) == 0 || strnicmp(src, "hsla(", 5) == 0)
-		{
-			src += 4;
-			if (*src == '(') src++;
-
-			vector<string> parts;
-			NLMISC::splitString(src, ",", parts);
-			if (parts.size() >= 3)
-			{
-				sint tmpv;
-				float h, s, l;
-				// hue
-				if (!fromString(parts[0], tmpv)) return false;
-				tmpv = ((tmpv % 360) + 360) % 360;
-				h = (float) tmpv / 360.0f;
-
-				// saturation
-				if (!getPercentage(tmpv, s, parts[1].c_str())) return false;
-				clamp(s, 0.0f, 1.0f);
-
-				// lightness
-				if (!getPercentage(tmpv, l, parts[2].c_str())) return false;
-				clamp(l, 0.0f, 1.0f);
-
-				CRGBA result;
-				hslToRgb(h, s, l, result);
-
-				// A
-				if (parts.size() == 4)
-				{
-					float tmpf;
-					if (!fromString(parts[3], tmpf)) return false;
-					if (parts[3].find_first_of("%") != std::string::npos)
-						tmpf /= 100;
-					clamp(tmpf, 0.0f, 1.0f);
-					result.A = 255 * tmpf;
-				}
-
-				dest = result;
-				return true;
-			}
-
-			return false;
-		}
-
-		{
-			// slow but should suffice for now
-			for(uint k = 0; k < sizeofarray(htmlColorNameToRGBA); ++k)
-			{
-				if (nlstricmp(src, htmlColorNameToRGBA[k].Name) == 0)
-				{
-					dest = htmlColorNameToRGBA[k].Color;
-					return true;
-				}
-			}
-			return false;
-		}
-	}
-
 	// ***************************************************************************
 
 	void CGroupHTML::beginElement (uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value)
@@ -1546,10 +1164,10 @@ namespace NLGUI
 			{
 			case HTML_HTML:
 				if (present[MY_HTML_HTML_STYLE] && value[MY_HTML_HTML_STYLE])
-					getStyleParams(value[MY_HTML_HTML_STYLE], _StyleDefault, _StyleDefault);
+					_Style.applyRootStyle(value[MY_HTML_HTML_STYLE]);
 
-				_Style = _StyleDefault;
-				setBackgroundColor(_Style.BackgroundColor);
+				_Style.Current = _Style.Root;
+				setBackgroundColor(_Style.Current.BackgroundColor);
 				break;
 			case HTML_HEAD:
 				_ReadingHeadTag = !_IgnoreHeadTag;
@@ -1607,17 +1225,17 @@ namespace NLGUI
 			{
 				registerAnchorName(MY_HTML_A);
 
-				pushStyle();
-				_Style.TextColor = LinkColor;
-				_Style.Underlined = true;
-				_Style.GlobalColor = LinkColorGlobalColor;
-				_Style.BackgroundColor.A = 0;
-				_Style.BackgroundColorOver.A = 0;
-				_Style.Width = -1;
-				_Style.Height = -1;
+				_Style.pushStyle();
+				_Style.Current.TextColor = LinkColor;
+				_Style.Current.Underlined = true;
+				_Style.Current.GlobalColor = LinkColorGlobalColor;
+				_Style.Current.BackgroundColor.A = 0;
+				_Style.Current.BackgroundColorOver.A = 0;
+				_Style.Current.Width = -1;
+				_Style.Current.Height = -1;
 
 				if (present[HTML_A_STYLE] && value[HTML_A_STYLE])
-					getStyleParams(value[HTML_A_STYLE], _Style, _StyleParams.back());
+					_Style.applyStyle(value[HTML_A_STYLE]);
 
 				_A.push_back(true);
 				_Link.push_back ("");
@@ -1656,7 +1274,7 @@ namespace NLGUI
 			{
 				_BlockLevelElement.push_back(true);
 				registerAnchorName(MY_HTML_DIV);
-				pushStyle();
+				_Style.pushStyle();
 
 				if (present[MY_HTML_DIV_NAME] && value[MY_HTML_DIV_NAME])
 					_DivName = value[MY_HTML_DIV_NAME];
@@ -1670,7 +1288,7 @@ namespace NLGUI
 					style = value[MY_HTML_DIV_STYLE];
 
 				if (!style.empty())
-					getStyleParams(style, _Style, _StyleParams.back());
+					_Style.applyStyle(style);
 
 				// use generic template system
 				if (_TrustedDomain && !instClass.empty() && instClass == "ryzom-ui-grouptemplate")
@@ -1746,19 +1364,19 @@ namespace NLGUI
 				break;
 			case HTML_FONT:
 			{
-				pushStyle();
+				_Style.pushStyle();
 				if (present[HTML_FONT_COLOR] && value[HTML_FONT_COLOR])
 				{
 					CRGBA color;
 					if (scanHTMLColor(value[HTML_FONT_COLOR], color))
-						_Style.TextColor = color;
+						_Style.Current.TextColor = color;
 				}
 
 				if (present[HTML_FONT_SIZE] && value[HTML_FONT_SIZE])
 				{
 					uint fontsize;
 					fromString(value[HTML_FONT_SIZE], fontsize);
-					_Style.FontSize = fontsize;
+					_Style.Current.FontSize = fontsize;
 				}
 			}
 				break;
@@ -1774,20 +1392,20 @@ namespace NLGUI
 				break;
 			case HTML_BODY:
 				{
-					pushStyle();
+					_Style.pushStyle();
 
 					string style;
 					if (present[HTML_BODY_STYLE] && value[HTML_BODY_STYLE])
 						style = value[HTML_BODY_STYLE];
 
 					if (!style.empty())
-						getStyleParams(style, _Style, _StyleParams.back());
+						_Style.applyStyle(style);
 
-					CRGBA bgColor = _Style.BackgroundColor;
+					CRGBA bgColor = _Style.Current.BackgroundColor;
 					if (present[HTML_BODY_BGCOLOR] && value[HTML_BODY_BGCOLOR])
 						scanHTMLColor(value[HTML_BODY_BGCOLOR], bgColor);
 
-					if (bgColor != _Style.BackgroundColor)
+					if (bgColor != _Style.Current.BackgroundColor)
 						setBackgroundColor(bgColor);
 
 					if (!style.empty())
@@ -1837,72 +1455,72 @@ namespace NLGUI
 				{
 					registerAnchorName(MY_HTML_H1);
 					newParagraph(PBeginSpace);
-					pushStyle();
-					_Style.FontSize = H1FontSize;
-					_Style.TextColor = H1Color;
-					_Style.GlobalColor = H1ColorGlobalColor;
+					_Style.pushStyle();
+					_Style.Current.FontSize = H1FontSize;
+					_Style.Current.TextColor = H1Color;
+					_Style.Current.GlobalColor = H1ColorGlobalColor;
 					if (present[MY_HTML_H1_STYLE] && value[MY_HTML_H1_STYLE])
-						getStyleParams(value[MY_HTML_H1_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_H1_STYLE]);
 				}
 				break;
 			case HTML_H2:
 				{
 					registerAnchorName(MY_HTML_H2);
 					newParagraph(PBeginSpace);
-					pushStyle();
-					_Style.FontSize = H2FontSize;
-					_Style.TextColor = H2Color;
-					_Style.GlobalColor = H2ColorGlobalColor;
+					_Style.pushStyle();
+					_Style.Current.FontSize = H2FontSize;
+					_Style.Current.TextColor = H2Color;
+					_Style.Current.GlobalColor = H2ColorGlobalColor;
 					if (present[MY_HTML_H2_STYLE] && value[MY_HTML_H2_STYLE])
-						getStyleParams(value[MY_HTML_H2_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_H2_STYLE]);
 				}
 				break;
 			case HTML_H3:
 				{
 					registerAnchorName(MY_HTML_H3);
 					newParagraph(PBeginSpace);
-					pushStyle();
-					_Style.FontSize = H3FontSize;
-					_Style.TextColor = H3Color;
-					_Style.GlobalColor = H3ColorGlobalColor;
+					_Style.pushStyle();
+					_Style.Current.FontSize = H3FontSize;
+					_Style.Current.TextColor = H3Color;
+					_Style.Current.GlobalColor = H3ColorGlobalColor;
 					if (present[MY_HTML_H3_STYLE] && value[MY_HTML_H3_STYLE])
-						getStyleParams(value[MY_HTML_H3_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_H3_STYLE]);
 				}
 				break;
 			case HTML_H4:
 				{
 					registerAnchorName(MY_HTML_H4);
 					newParagraph(PBeginSpace);
-					pushStyle();
-					_Style.FontSize = H4FontSize;
-					_Style.TextColor = H4Color;
-					_Style.GlobalColor = H4ColorGlobalColor;
+					_Style.pushStyle();
+					_Style.Current.FontSize = H4FontSize;
+					_Style.Current.TextColor = H4Color;
+					_Style.Current.GlobalColor = H4ColorGlobalColor;
 					if (present[MY_HTML_H4_STYLE] && value[MY_HTML_H4_STYLE])
-						getStyleParams(value[MY_HTML_H4_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_H4_STYLE]);
 				}
 				break;
 			case HTML_H5:
 				{
 					registerAnchorName(MY_HTML_H5);
 					newParagraph(PBeginSpace);
-					pushStyle();
-					_Style.FontSize = H5FontSize;
-					_Style.TextColor = H5Color;
-					_Style.GlobalColor = H5ColorGlobalColor;
+					_Style.pushStyle();
+					_Style.Current.FontSize = H5FontSize;
+					_Style.Current.TextColor = H5Color;
+					_Style.Current.GlobalColor = H5ColorGlobalColor;
 					if (present[MY_HTML_H5_STYLE] && value[MY_HTML_H5_STYLE])
-						getStyleParams(value[MY_HTML_H5_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_H5_STYLE]);
 				}
 				break;
 			case HTML_H6:
 				{
 					registerAnchorName(MY_HTML_H6);
 					newParagraph(PBeginSpace);
-					pushStyle();
-					_Style.FontSize = H6FontSize;
-					_Style.TextColor = H6Color;
-					_Style.GlobalColor = H6ColorGlobalColor;
+					_Style.pushStyle();
+					_Style.Current.FontSize = H6FontSize;
+					_Style.Current.TextColor = H6Color;
+					_Style.Current.GlobalColor = H6ColorGlobalColor;
 					if (present[MY_HTML_H6_STYLE] && value[MY_HTML_H6_STYLE])
-						getStyleParams(value[MY_HTML_H6_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_H6_STYLE]);
 				}
 				break;
 			case HTML_IMG:
@@ -1912,24 +1530,24 @@ namespace NLGUI
 					{
 						float tmpf;
 						std::string id;
-						CStyleParams style;
-						style.FontSize = _Style.FontSize;
+
+						_Style.pushStyle();
 
 						if (present[MY_HTML_IMG_ID] && value[MY_HTML_IMG_ID])
 							id = value[MY_HTML_IMG_ID];
 
 						if (present[MY_HTML_IMG_WIDTH] && value[MY_HTML_IMG_WIDTH])
-							getPercentage(style.Width, tmpf, value[MY_HTML_IMG_WIDTH]);
+							getPercentage(_Style.Current.Width, tmpf, value[MY_HTML_IMG_WIDTH]);
 						if (present[MY_HTML_IMG_HEIGHT] && value[MY_HTML_IMG_HEIGHT])
-							getPercentage(style.Height, tmpf, value[MY_HTML_IMG_HEIGHT]);
+							getPercentage(_Style.Current.Height, tmpf, value[MY_HTML_IMG_HEIGHT]);
 
 						// Get the global color name
 						if (present[MY_HTML_IMG_GLOBAL_COLOR])
-							style.GlobalColor = true;
+							_Style.Current.GlobalColor = true;
 
 						// width, height from inline css
 						if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE])
-							getStyleParams(value[MY_HTML_IMG_STYLE], style, _Style);
+							_Style.applyStyle(value[MY_HTML_IMG_STYLE]);
 
 						// Tooltip
 						const char *tooltip = NULL;
@@ -1952,13 +1570,13 @@ namespace NLGUI
 						{
 							string params = "name=" + getId() + "|url=" + getLink ();
 							addButton(CCtrlButton::PushButton, id, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC],
-								overSrc, "browse", params.c_str(), tooltip, style);
+								overSrc, "browse", params.c_str(), tooltip, _Style.Current);
 						}
 						else
 						if (tooltip || !overSrc.empty())
 						{
 							addButton(CCtrlButton::PushButton, id, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC],
-								overSrc, "", "", tooltip, style);
+								overSrc, "", "", tooltip, _Style.Current);
 						}
 						else
 						{
@@ -1979,8 +1597,10 @@ namespace NLGUI
 									reloadImg = true;
 							}
 
-							addImage(id, value[MY_HTML_IMG_SRC], reloadImg, style);
+							addImage(id, value[MY_HTML_IMG_SRC], reloadImg, _Style.Current);
 						}
+
+						_Style.popStyle();
 					}
 				}
 				break;
@@ -2010,22 +1630,22 @@ namespace NLGUI
 					if (present[MY_HTML_INPUT_TYPE] && value[MY_HTML_INPUT_TYPE])
 					{
 						// by default not inherited, font family defaults to system font
-						pushStyle();
-						_Style.TextColor = TextColor;
-						_Style.FontSize = TextFontSize;
-						_Style.FontWeight = FONT_WEIGHT_NORMAL;
-						_Style.FontOblique = false;
-						_Style.TextShadow = STextShadow(true);
-						_Style.Width = -1;
-						_Style.Height = -1;
+						_Style.pushStyle();
+						_Style.Current.TextColor = TextColor;
+						_Style.Current.FontSize = TextFontSize;
+						_Style.Current.FontWeight = FONT_WEIGHT_NORMAL;
+						_Style.Current.FontOblique = false;
+						_Style.Current.TextShadow = CStyleParams::STextShadow(true);
+						_Style.Current.Width = -1;
+						_Style.Current.Height = -1;
 						// by default background texture is transparent,
 						// using alpha value to decide if to change it to 'blank.tga' for coloring
-						_Style.BackgroundColor.A = 0;
-						_Style.BackgroundColorOver.A = 0;
+						_Style.Current.BackgroundColor.A = 0;
+						_Style.Current.BackgroundColorOver.A = 0;
 
 						// Global color flag
 						if (present[MY_HTML_INPUT_GLOBAL_COLOR])
-							_Style.GlobalColor = true;
+							_Style.Current.GlobalColor = true;
 
 						// Tooltip
 						const char *tooltip = NULL;
@@ -2033,7 +1653,7 @@ namespace NLGUI
 							tooltip = value[MY_HTML_INPUT_ALT];
 
 						if (present[MY_HTML_INPUT_STYLE] && value[MY_HTML_INPUT_STYLE])
-							getStyleParams(value[MY_HTML_INPUT_STYLE], _Style, _StyleParams.back());
+							_Style.applyStyle(value[MY_HTML_INPUT_STYLE]);
 
 						string type = toLower(value[MY_HTML_INPUT_TYPE]);
 						if (type == "image")
@@ -2053,7 +1673,7 @@ namespace NLGUI
 
 							// Add the ctrl button
 							addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
-								"html_submit_form", param.c_str(), tooltip, _Style);
+								"html_submit_form", param.c_str(), tooltip, _Style.Current);
 						}
 						if (type == "button" || type == "submit")
 						{
@@ -2108,7 +1728,7 @@ namespace NLGUI
 								if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
 								if (ctrlButton)
 								{
-									ctrlButton->setModulateGlobalColorAll (_Style.GlobalColor);
+									ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
 
 									// Translate the tooltip
 									if (tooltip)
@@ -2125,7 +1745,7 @@ namespace NLGUI
 
 									ctrlButton->setText(ucstring::makeFromUtf8(text));
 
-									setTextButtonStyle(ctrlButton, _Style);
+									setTextButtonStyle(ctrlButton, _Style.Current);
 								}
 								getParagraph()->addChild (buttonGroup);
 								paragraphChange ();
@@ -2193,7 +1813,7 @@ namespace NLGUI
 							checked = (present[MY_HTML_INPUT_CHECKED] && value[MY_HTML_INPUT_CHECKED]);
 
 							// Add the ctrl button
-							CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style);
+							CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style.Current);
 							if (checkbox)
 							{
 								if (btnType == CCtrlButton::RadioButton)
@@ -2251,14 +1871,16 @@ namespace NLGUI
 							}
 						}
 
-						popStyle();
+						_Style.popStyle();
 					}
 				}
 				break;
 			case HTML_SELECT:
 				if (!(_Forms.empty()))
 				{
-					CStyleParams style;
+					_Style.pushStyle();
+					_Style.Current.Width = -1;
+					_Style.Current.Height = -1;
 
 					// A select box
 					string name;
@@ -2272,7 +1894,7 @@ namespace NLGUI
 					if (present[HTML_SELECT_MULTIPLE] && value[HTML_SELECT_MULTIPLE])
 						multiple = true;
 					if (present[HTML_SELECT_STYLE] && value[HTML_SELECT_STYLE])
-						getStyleParams(value[HTML_SELECT_STYLE], style, _Style);
+						_Style.applyStyle(value[HTML_SELECT_STYLE]);
 
 					CGroupHTML::CForm::CEntry entry;
 					entry.Name = name;
@@ -2286,14 +1908,14 @@ namespace NLGUI
 							if (size < 1)
 								size = 4;
 
-							if (style.Width > -1)
-								sb->setMinW(style.Width);
+							if (_Style.Current.Width > -1)
+								sb->setMinW(_Style.Current.Width);
 
-							if (style.Height > -1)
-								sb->setMinH(style.Height);
+							if (_Style.Current.Height > -1)
+								sb->setMinH(_Style.Current.Height);
 
 							sb->setMaxVisibleLine(size);
-							sb->setFontSize(style.FontSize);
+							sb->setFontSize(_Style.Current.FontSize);
 						}
 
 						entry.SelectBox = sb;
@@ -2308,10 +1930,12 @@ namespace NLGUI
 							// create view text
 							cb->updateCoords();
 							if (cb->getViewText())
-								setTextStyle(cb->getViewText(), style);
+								setTextStyle(cb->getViewText(), _Style.Current);
 						}
 					}
 					_Forms.back().Entries.push_back (entry);
+
+					_Style.popStyle();
 				}
 			break;
 			case HTML_OPTION:
@@ -2354,9 +1978,9 @@ namespace NLGUI
 					if (present[HTML_LI_VALUE] && value[HTML_LI_VALUE])
 						fromString(value[HTML_LI_VALUE], _UL.back().Value);
 
-					pushStyle();
+					_Style.pushStyle();
 					if (present[HTML_LI_STYLE] && value[HTML_LI_STYLE])
-						getStyleParams(value[HTML_LI_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[HTML_LI_STYLE]);
 
 					ucstring str;
 					str.fromUtf8(_UL.back().getListMarkerText());
@@ -2377,18 +2001,18 @@ namespace NLGUI
 			case HTML_P:
 				{
 					newParagraph(PBeginSpace);
-					pushStyle();
+					_Style.pushStyle();
 					if (present[MY_HTML_P_STYLE] && value[MY_HTML_P_STYLE])
-						getStyleParams(value[MY_HTML_P_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_P_STYLE]);
 				}
 				break;
 			case HTML_PRE:
 				{
-					pushStyle();
-					_Style.FontFamily = "monospace";
+					_Style.pushStyle();
+					_Style.Current.FontFamily = "monospace";
 
 					if (present[HTML_PRE_STYLE] && value[HTML_PRE_STYLE])
-						getStyleParams(value[HTML_PRE_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[HTML_PRE_STYLE]);
 
 
 					_PRE.push_back(true);
@@ -2396,7 +2020,7 @@ namespace NLGUI
 				break;
 			case HTML_TABLE:
 				{
-					pushStyle();
+					_Style.pushStyle();
 					registerAnchorName(MY_HTML_TABLE);
 
 					// Get cells parameters
@@ -2416,7 +2040,7 @@ namespace NLGUI
 					if (present[MY_HTML_TABLE_CELLPADDING] && value[MY_HTML_TABLE_CELLPADDING])
 						fromString(value[MY_HTML_TABLE_CELLPADDING], table->CellPadding);
 					if (present[MY_HTML_TABLE_STYLE] && value[MY_HTML_TABLE_STYLE])
-						getStyleParams(value[MY_HTML_TABLE_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_TABLE_STYLE]);
 
 					table->setMarginLeft(getIndent());
 					addHtmlGroup (table, 0);
@@ -2436,17 +2060,17 @@ namespace NLGUI
 					// Get cells parameters
 					getCellsParameters (MY_HTML_TD, true);
 
-					pushStyle();
+					_Style.pushStyle();
 					if (element_number == HTML_TH)
 					{
-						_Style.FontWeight = FONT_WEIGHT_BOLD;
+						_Style.Current.FontWeight = FONT_WEIGHT_BOLD;
 						// center if not specified otherwise. TD/TH present/value arrays have same indices
 						if (!(present[MY_HTML_TD_ALIGN] && value[MY_HTML_TD_ALIGN]))
 							_CellParams.back().Align = CGroupCell::Center;
 					}
 
 					if (present[MY_HTML_TD_STYLE] && value[MY_HTML_TD_STYLE])
-						getStyleParams(value[MY_HTML_TD_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_TD_STYLE]);
 
 					CGroupTable *table = getTable();
 					if (table)
@@ -2527,21 +2151,21 @@ namespace NLGUI
 				}
 				break;
 			case HTML_TEXTAREA:
-				pushStyle();
+				_Style.pushStyle();
 				_PRE.push_back(true);
 
 				// not inherited by default, font family defaults to system font
-				_Style.TextColor = TextColor;
-				_Style.FontWeight = FONT_WEIGHT_NORMAL;
-				_Style.FontOblique = false;
-				_Style.FontSize = TextFontSize;
-				_Style.TextShadow = STextShadow(true);
-				_Style.Width = -1;
-				_Style.Height = -1;
-				_Style.BackgroundColor.A = 0;
+				_Style.Current.TextColor = TextColor;
+				_Style.Current.FontWeight = FONT_WEIGHT_NORMAL;
+				_Style.Current.FontOblique = false;
+				_Style.Current.FontSize = TextFontSize;
+				_Style.Current.TextShadow = CStyleParams::STextShadow(true);
+				_Style.Current.Width = -1;
+				_Style.Current.Height = -1;
+				_Style.Current.BackgroundColor.A = 0;
 
 				if (present[MY_HTML_TEXTAREA_STYLE] && value[MY_HTML_TEXTAREA_STYLE])
-					getStyleParams(value[MY_HTML_TEXTAREA_STYLE], _Style, _StyleParams.back());
+					_Style.applyStyle(value[MY_HTML_TEXTAREA_STYLE]);
 
 				// Got one form ?
 				if (!(_Forms.empty()))
@@ -2595,9 +2219,9 @@ namespace NLGUI
 					if (!_TR.empty())
 						_TR.back() = true;
 
-					pushStyle();
+					_Style.pushStyle();
 					if (present[MY_HTML_TR_STYLE] && value[MY_HTML_TR_STYLE])
-						getStyleParams(value[MY_HTML_TR_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_TR_STYLE]);
 				}
 				break;
 			case HTML_UL:
@@ -2612,9 +2236,9 @@ namespace NLGUI
 				_Indent.push_back(getIndent() + ULIndent);
 				endParagraph();
 
-				pushStyle();
+				_Style.pushStyle();
 				if (present[HTML_UL_STYLE] && value[HTML_UL_STYLE])
-					getStyleParams(value[HTML_UL_STYLE], _Style, _StyleParams.back());
+					_Style.applyStyle(value[HTML_UL_STYLE]);
 				break;
 			case HTML_OBJECT:
 				_ObjectType.clear();
@@ -2634,40 +2258,40 @@ namespace NLGUI
 				break;
 			case HTML_SPAN:
 				{
-					pushStyle();
+					_Style.pushStyle();
 
 					if (present[MY_HTML_SPAN_STYLE] && value[MY_HTML_SPAN_STYLE])
-						getStyleParams(value[MY_HTML_SPAN_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[MY_HTML_SPAN_STYLE]);
 				}
 				break;
 			case HTML_DEL:
 				{
-					pushStyle();
-					_Style.StrikeThrough = true;
+					_Style.pushStyle();
+					_Style.Current.StrikeThrough = true;
 				}
 				break;
 			case HTML_U:
 				{
-					pushStyle();
-					_Style.Underlined = true;
+					_Style.pushStyle();
+					_Style.Current.Underlined = true;
 				}
 				break;
 			case HTML_EM:
 				{
-					pushStyle();
-					_Style.FontOblique = true;
+					_Style.pushStyle();
+					_Style.Current.FontOblique = true;
 				}
 				break;
 			case HTML_STRONG:
 				{
-					pushStyle();
-					_Style.FontWeight = FONT_WEIGHT_BOLD;
+					_Style.pushStyle();
+					_Style.Current.FontWeight = FONT_WEIGHT_BOLD;
 				}
 				break;
 			case HTML_SMALL:
 				{
-					pushStyle();
-					_Style.FontSize = getFontSizeSmaller();
+					_Style.pushStyle();
+					_Style.Current.FontSize = _Style.getFontSizeSmaller();
 				}
 				break;
 			case HTML_STYLE:
@@ -2679,9 +2303,9 @@ namespace NLGUI
 					_DL.push_back(HTMLDListElement());
 					_LI = _DL.size() > 1 || !_UL.empty();
 					endParagraph();
-					pushStyle();
+					_Style.pushStyle();
 					if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
-						getStyleParams(value[HTML_GEN_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[HTML_GEN_STYLE]);
 				}
 				break;
 			case HTML_DT:
@@ -2692,19 +2316,19 @@ namespace NLGUI
 					{
 						_DL.back().DD = false;
 						popIfNotEmpty(_Indent);
-						popStyle();
+						_Style.popStyle();
 					}
 
 					// close if still open
 					if (_DL.back().DT)
-						popStyle();
+						_Style.popStyle();
 
 					_DL.back().DT = true;
 
-					pushStyle();
-					_Style.FontWeight = FONT_WEIGHT_BOLD;
+					_Style.pushStyle();
+					_Style.Current.FontWeight = FONT_WEIGHT_BOLD;
 					if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
-						getStyleParams(value[HTML_GEN_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[HTML_GEN_STYLE]);
 
 					if (!_LI)
 					{
@@ -2724,22 +2348,22 @@ namespace NLGUI
 					if (_DL.back().DT)
 					{
 						_DL.back().DT = false;
-						popStyle();
+						_Style.popStyle();
 					}
 
 					if (_DL.back().DD)
 					{
 						_DL.back().DD = false;
-						popStyle();
+						_Style.popStyle();
 						popIfNotEmpty(_Indent);
 					}
 
 					_DL.back().DD = true;
 					_Indent.push_back(getIndent() + ULIndent);
 
-					pushStyle();
+					_Style.pushStyle();
 					if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
-						getStyleParams(value[HTML_GEN_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[HTML_GEN_STYLE]);
 
 					if (!_LI)
 					{
@@ -2754,7 +2378,7 @@ namespace NLGUI
 				break;
 			case HTML_OL:
 				{
-					pushStyle();
+					_Style.pushStyle();
 					sint32 start = 1;
 					std::string type("1");
 
@@ -2763,7 +2387,7 @@ namespace NLGUI
 					if (present[HTML_OL_TYPE] && value[HTML_OL_TYPE])
 						type = value[HTML_OL_TYPE];
 					if (present[HTML_OL_STYLE] && value[HTML_OL_STYLE])
-						getStyleParams(value[HTML_OL_STYLE], _Style, _StyleParams.back());
+						_Style.applyStyle(value[HTML_OL_STYLE]);
 
 					_UL.push_back(HTMLOListElement(start, type));
 					// if LI is already present
@@ -2779,34 +2403,35 @@ namespace NLGUI
 					CInterfaceGroup *sep = CWidgetManager::getInstance()->getParser()->createGroupInstance("html_hr", "", NULL, 0);
 					if (sep)
 					{
-						CStyleParams style;
-						style.FontSize = _Style.FontSize;
-						style.TextColor = CRGBA(120, 120, 120, 255);
-						style.Height = 0;
-						style.Width = 0;
+						_Style.pushStyle();
+						_Style.Current.TextColor = CRGBA(120, 120, 120, 255);
+						_Style.Current.Height = -1;
+						_Style.Current.Width = -1;
 
 						if (present[HTML_HR_STYLE] && value[HTML_HR_STYLE])
-							getStyleParams(value[HTML_HR_STYLE], style, _Style);
+							_Style.applyStyle(value[HTML_HR_STYLE]);
 
 						CViewBitmap *bitmap = dynamic_cast<CViewBitmap*>(sep->getView("hr"));
 						if (bitmap)
 						{
-							bitmap->setColor(style.TextColor);
-							if (style.Width > 0)
+							bitmap->setColor(_Style.Current.TextColor);
+							if (_Style.Current.Width > 0)
 							{
-								clamp(style.Width, 1, 32000);
-								bitmap->setW(style.Width);
+								clamp(_Style.Current.Width, 1, 32000);
+								bitmap->setW(_Style.Current.Width);
 								bitmap->setSizeRef(CInterfaceElement::none);
 							}
-							if (style.Height > 0)
+							if (_Style.Current.Height > 0)
 							{
-								clamp(style.Height, 1, 1000);
-								bitmap->setH(style.Height);
+								clamp(_Style.Current.Height, 1, 1000);
+								bitmap->setH(_Style.Current.Height);
 							}
 						}
 
 						getParagraph()->addChild(sep);
 						endParagraph();
+
+						_Style.popStyle();
 					}
 				}
 				break;
@@ -2827,13 +2452,13 @@ namespace NLGUI
 				_ReadingHeadTag = false;
 				break;
 			case HTML_BODY:
-				popStyle();
+				_Style.popStyle();
 				break;
 			case HTML_FONT:
-				popStyle();
+				_Style.popStyle();
 			break;
 			case HTML_A:
-				popStyle();
+				_Style.popStyle();
 				popIfNotEmpty (_A);
 				popIfNotEmpty (_Link);
 				popIfNotEmpty (_LinkTitle);
@@ -2845,19 +2470,19 @@ namespace NLGUI
 			case HTML_H4:
 			case HTML_H5:
 			case HTML_H6:
-				popStyle();
+				_Style.popStyle();
 				endParagraph();
 				break;
 			case HTML_P:
-				popStyle();
+				_Style.popStyle();
 				endParagraph();
 				break;
 			case HTML_PRE:
-				popStyle();
+				_Style.popStyle();
 				popIfNotEmpty (_PRE);
 				break;
 			case HTML_DIV:
-				popStyle();
+				_Style.popStyle();
 				if (isBlockLevelElement())
 				{
 					endParagraph();
@@ -2868,7 +2493,7 @@ namespace NLGUI
 				break;
 
 			case HTML_TABLE:
-				popStyle();
+				_Style.popStyle();
 				popIfNotEmpty (_CellParams);
 				popIfNotEmpty (_TR);
 				popIfNotEmpty (_Cells);
@@ -2880,13 +2505,13 @@ namespace NLGUI
 			case HTML_TH:
 				// no break;
 			case HTML_TD:
-				popStyle();
+				_Style.popStyle();
 				popIfNotEmpty (_CellParams);
 				if (!_Cells.empty())
 					_Cells.back() = NULL;
 				break;
 			case HTML_TR:
-				popStyle();
+				_Style.popStyle();
 				popIfNotEmpty (_CellParams);
 				break;
 			case HTML_TEXTAREA:
@@ -2905,7 +2530,7 @@ namespace NLGUI
 						}
 					}
 
-					popStyle();
+					_Style.popStyle();
 					popIfNotEmpty (_PRE);
 				}
 				break;
@@ -3013,14 +2638,14 @@ namespace NLGUI
 				if (!_UL.empty())
 				{
 					endParagraph();
-					popStyle();
+					_Style.popStyle();
 					popIfNotEmpty(_UL);
 					popIfNotEmpty(_Indent);
 				}
 				break;
 			case HTML_LI:
 				{
-					popStyle();
+					_Style.popStyle();
 				}
 				break;
 			case HTML_DL:
@@ -3031,25 +2656,25 @@ namespace NLGUI
 					// unclosed DT
 					if (_DL.back().DT)
 					{
-						popStyle();
+						_Style.popStyle();
 					}
 
 					// unclosed DD
 					if (_DL.back().DD)
 					{
 						popIfNotEmpty(_Indent);
-						popStyle();
+						_Style.popStyle();
 					}
 
 					popIfNotEmpty (_DL);
-					popStyle();
+					_Style.popStyle();
 				}
 				break;
 			case HTML_DT:
 				if (!_DL.empty())
 				{
 					if (_DL.back().DT)
-						popStyle();
+						_Style.popStyle();
 					_DL.back().DT = false;
 				}
 				break;
@@ -3061,27 +2686,27 @@ namespace NLGUI
 					{
 						_DL.back().DD = false;
 						popIfNotEmpty(_Indent);
-						popStyle();
+						_Style.popStyle();
 					}
 				}
 				break;
 			case HTML_SPAN:
-				popStyle();
+				_Style.popStyle();
 				break;
 			case HTML_DEL:
-				popStyle();
+				_Style.popStyle();
 				break;
 			case HTML_U:
-				popStyle();
+				_Style.popStyle();
 				break;
 			case HTML_EM:
-				popStyle();
+				_Style.popStyle();
 				break;
 			case HTML_STRONG:
-				popStyle();
+				_Style.popStyle();
 				break;
 			case HTML_SMALL:
-				popStyle();
+				_Style.popStyle();
 				break;
 			case HTML_STYLE:
 			case HTML_SCRIPT:
@@ -4508,34 +4133,36 @@ namespace NLGUI
 				paragraphChange ();
 			}
 
+			CStyleParams &style = _Style.Current;
+
 			// Text added ?
 			bool added = false;
-			bool embolden = _Style.FontWeight >= FONT_WEIGHT_BOLD;
+			bool embolden = style.FontWeight >= FONT_WEIGHT_BOLD;
 
 			// Number of child in this paragraph
 			if (_CurrentViewLink)
 			{
 				bool skipLine = !_CurrentViewLink->getText().empty() && *(_CurrentViewLink->getText().rbegin()) == (ucchar) '\n';
-				bool sameShadow = _Style.TextShadow.Enabled && _CurrentViewLink->getShadow();
-				if (sameShadow && _Style.TextShadow.Enabled)
+				bool sameShadow = style.TextShadow.Enabled && _CurrentViewLink->getShadow();
+				if (sameShadow && style.TextShadow.Enabled)
 				{
 					sint sx, sy;
 					_CurrentViewLink->getShadowOffset(sx, sy);
-					sameShadow = (_Style.TextShadow.Color == _CurrentViewLink->getShadowColor());
-					sameShadow = sameShadow && (_Style.TextShadow.Outline == _CurrentViewLink->getShadowOutline());
-					sameShadow = sameShadow && (_Style.TextShadow.X == sx) && (_Style.TextShadow.Y == sy);
+					sameShadow = (style.TextShadow.Color == _CurrentViewLink->getShadowColor());
+					sameShadow = sameShadow && (style.TextShadow.Outline == _CurrentViewLink->getShadowOutline());
+					sameShadow = sameShadow && (style.TextShadow.X == sx) && (style.TextShadow.Y == sy);
 				}
 				// Compatible with current parameters ?
 				if (!skipLine && sameShadow &&
-					(_Style.TextColor == _CurrentViewLink->getColor()) &&
-					(_Style.FontFamily == _CurrentViewLink->getFontName()) &&
-					(_Style.FontSize == (uint)_CurrentViewLink->getFontSize()) &&
-					(_Style.Underlined == _CurrentViewLink->getUnderlined()) &&
-					(_Style.StrikeThrough == _CurrentViewLink->getStrikeThrough()) &&
+					(style.TextColor == _CurrentViewLink->getColor()) &&
+					(style.FontFamily == _CurrentViewLink->getFontName()) &&
+					(style.FontSize == (uint)_CurrentViewLink->getFontSize()) &&
+					(style.Underlined == _CurrentViewLink->getUnderlined()) &&
+					(style.StrikeThrough == _CurrentViewLink->getStrikeThrough()) &&
 					(embolden == _CurrentViewLink->getEmbolden()) &&
-					(_Style.FontOblique == _CurrentViewLink->getOblique()) &&
+					(style.FontOblique == _CurrentViewLink->getOblique()) &&
 					(getLink() == _CurrentViewLink->Link) &&
-					(_Style.GlobalColor == _CurrentViewLink->getModulateGlobalColor()))
+					(style.GlobalColor == _CurrentViewLink->getModulateGlobalColor()))
 				{
 					// Concat the text
 					_CurrentViewLink->setText(_CurrentViewLink->getText()+tmpStr);
@@ -4574,7 +4201,7 @@ namespace NLGUI
 							ctrlButton->setDefaultContextHelp(ucstring::makeFromUtf8(getLinkTitle()));
 							ctrlButton->setText(tmpStr);
 
-							setTextButtonStyle(ctrlButton, _Style);
+							setTextButtonStyle(ctrlButton, style);
 						}
 						getParagraph()->addChild (buttonGroup);
 						paragraphChange ();
@@ -4597,10 +4224,10 @@ namespace NLGUI
 						}
 					}
 					newLink->setText(tmpStr);
-					newLink->setMultiLineSpace((uint)((float)(_Style.FontSize)*LineSpaceFontFactor));
+					newLink->setMultiLineSpace((uint)((float)(style.FontSize)*LineSpaceFontFactor));
 					newLink->setMultiLine(true);
-					newLink->setModulateGlobalColor(_Style.GlobalColor);
-					setTextStyle(newLink, _Style);
+					newLink->setModulateGlobalColor(style.GlobalColor);
+					setTextStyle(newLink, style);
 					// newLink->setLineAtBottom (true);
 
 					registerAnchor(newLink);
@@ -4705,22 +4332,23 @@ namespace NLGUI
 		// No more text in this text view
 		_CurrentViewLink = NULL;
 
+		CStyleParams &style = _Style.Current;
 		{
 			// override cols/rows values from style
-			if (_Style.Width > 0) cols = _Style.Width / _Style.FontSize;
-			if (_Style.Height > 0) rows = _Style.Height / _Style.FontSize;
+			if (style.Width > 0) cols = style.Width / style.FontSize;
+			if (style.Height > 0) rows = style.Height / style.FontSize;
 
 			// Not added ?
 			std::vector<std::pair<std::string,std::string> > templateParams;
-			templateParams.push_back (std::pair<std::string,std::string> ("w", toString (cols*_Style.FontSize)));
+			templateParams.push_back (std::pair<std::string,std::string> ("w", toString (cols*style.FontSize)));
 			templateParams.push_back (std::pair<std::string,std::string> ("id", name));
 			templateParams.push_back (std::pair<std::string,std::string> ("prompt", ""));
 			templateParams.push_back (std::pair<std::string,std::string> ("multiline", multiLine?"true":"false"));
-			templateParams.push_back (std::pair<std::string,std::string> ("fontsize", toString (_Style.FontSize)));
-			templateParams.push_back (std::pair<std::string,std::string> ("color", _Style.TextColor.toString()));
-			if (_Style.FontWeight >= FONT_WEIGHT_BOLD)
+			templateParams.push_back (std::pair<std::string,std::string> ("fontsize", toString (style.FontSize)));
+			templateParams.push_back (std::pair<std::string,std::string> ("color", style.TextColor.toString()));
+			if (style.FontWeight >= FONT_WEIGHT_BOLD)
 				templateParams.push_back (std::pair<std::string,std::string> ("fontweight", "bold"));
-			if (_Style.FontOblique)
+			if (style.FontOblique)
 				templateParams.push_back (std::pair<std::string,std::string> ("fontstyle", "oblique"));
 			if (multiLine)
 				templateParams.push_back (std::pair<std::string,std::string> ("multi_min_line", toString(rows)));
@@ -4729,13 +4357,13 @@ namespace NLGUI
 			templateParams.push_back (std::pair<std::string,std::string> ("enter_recover_focus", "false"));
 			if (maxlength > 0)
 				templateParams.push_back (std::pair<std::string,std::string> ("max_num_chars", toString(maxlength)));
-			templateParams.push_back (std::pair<std::string,std::string> ("shadow", toString(_Style.TextShadow.Enabled)));
-			if (_Style.TextShadow.Enabled)
+			templateParams.push_back (std::pair<std::string,std::string> ("shadow", toString(style.TextShadow.Enabled)));
+			if (style.TextShadow.Enabled)
 			{
-				templateParams.push_back (std::pair<std::string,std::string> ("shadow_x", toString(_Style.TextShadow.X)));
-				templateParams.push_back (std::pair<std::string,std::string> ("shadow_y", toString(_Style.TextShadow.Y)));
-				templateParams.push_back (std::pair<std::string,std::string> ("shadow_color", _Style.TextShadow.Color.toString()));
-				templateParams.push_back (std::pair<std::string,std::string> ("shadow_outline", toString(_Style.TextShadow.Outline)));
+				templateParams.push_back (std::pair<std::string,std::string> ("shadow_x", toString(style.TextShadow.X)));
+				templateParams.push_back (std::pair<std::string,std::string> ("shadow_y", toString(style.TextShadow.Y)));
+				templateParams.push_back (std::pair<std::string,std::string> ("shadow_color", style.TextShadow.Color.toString()));
+				templateParams.push_back (std::pair<std::string,std::string> ("shadow_outline", toString(style.TextShadow.Outline)));
 			}
 
 			CInterfaceGroup *textArea = CWidgetManager::getInstance()->getParser()->createGroupInstance (templateName.c_str(),
@@ -4749,13 +4377,13 @@ namespace NLGUI
 				if (eb)
 				{
 					eb->setInputString(decodeHTMLEntities(content));
-					if (_Style.BackgroundColor.A > 0)
+					if (style.BackgroundColor.A > 0)
 					{
 						CViewBitmap *bg = dynamic_cast<CViewBitmap*>(eb->getView("bg"));
 						if (bg)
 						{
 							bg->setTexture("blank.tga");
-							bg->setColor(_Style.BackgroundColor);
+							bg->setColor(style.BackgroundColor);
 						}
 					}
 				}
@@ -6411,423 +6039,11 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::resetCssStyle()
 	{
-		_StyleDefault = CStyleParams();
-		_StyleDefault.TextColor = TextColor;
-		_StyleDefault.FontSize = TextFontSize;
-		_StyleDefault.BackgroundColor = BgColor;
-
-		_Style = _StyleDefault;
-		_StyleParams.clear();
-	}
-
-	// ***************************************************************************
-	// CGroupHTML::CStyleParams style;
-	// style.FontSize;    // font-size: 10px;
-	// style.TextColor;   // color: #ABCDEF;
-	// style.Underlined;  // text-decoration: underline;     text-decoration-line: underline;
-	// style.StrikeThrough; // text-decoration: line-through;  text-decoration-line: line-through;
-	void CGroupHTML::getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current)
-	{
-		float tmpf;
-		TStyle styles = parseStyle(styleString);
-		TStyle::iterator it;
-
-		// first pass: get font-size for 'em' sizes
-		for (it=styles.begin(); it != styles.end(); ++it)
-		{
-			if (it->first == "font")
-			{
-				if (it->second == "inherit")
-				{
-					style.FontSize = current.FontSize;
-					style.FontFamily = current.FontFamily;
-					style.FontWeight = current.FontWeight;
-					style.FontOblique = current.FontOblique;
-				}
-			}
-			else
-			if (it->first == "font-size")
-			{
-				if (it->second == "inherit")
-				{
-					style.FontSize = current.FontSize;
-				}
-				else
-				{
-					std::string unit;
-					if (getCssLength(tmpf, unit, it->second.c_str()))
-					{
-						if (unit == "rem")
-							style.FontSize = _StyleDefault.FontSize * tmpf;
-						else if (unit == "em")
-							style.FontSize = current.FontSize * tmpf;
-						else if (unit == "pt")
-							style.FontSize = tmpf / 0.75f;
-						else if (unit == "%")
-							style.FontSize = current.FontSize * tmpf / 100.f;
-						else
-							style.FontSize = tmpf;
-					}
-				}
-			}
-		}
-
-		// second pass: rest of style
-		for (it=styles.begin(); it != styles.end(); ++it)
-		{
-			if (it->first == "border")
-			{
-				sint32 b;
-				if (it->second == "none")
-					style.BorderWidth = 0;
-				else
-				if (fromString(it->second, b))
-					style.BorderWidth = b;
-			}
-			else
-			if (it->first == "font-style")
-			{
-				if (it->second == "inherit")
-					style.FontOblique = current.FontOblique;
-				else
-				if (it->second == "italic" || it->second == "oblique")
-					style.FontOblique = true;
-			}
-			else
-			if (it->first == "font-family")
-			{
-				if (it->second == "inherit")
-					style.FontFamily = current.FontFamily;
-				else
-					style.FontFamily = it->second;
-			}
-			else
-			if (it->first == "font-weight")
-			{
-				// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
-				uint weight = 400;
-				if (it->second == "inherit")
-					weight = current.FontWeight;
-				else
-				if (it->second == "normal")
-					weight = 400;
-				else
-				if (it->second == "bold")
-					weight = 700;
-				else
-				if (it->second == "lighter")
-				{
-					const uint lighter[] = {100, 100, 100, 100, 100, 400, 400, 700, 700};
-					uint index = current.FontWeight / 100 - 1;
-					clamp(index, 1u, 9u);
-					weight = lighter[index-1];
-				}
-				else
-				if (it->second == "bolder")
-				{
-					const uint bolder[] =  {400, 400, 400, 700, 700, 900, 900, 900, 900};
-					uint index = current.FontWeight / 100 + 1;
-					clamp(index, 1u, 9u);
-					weight = bolder[index-1];
-				}
-				else
-				if (fromString(it->second, weight))
-				{
-					weight = (weight / 100);
-					clamp(weight, 1u, 9u);
-					weight *= 100;
-				}
-				style.FontWeight = weight;
-			}
-			else
-			if (it->first == "color")
-				if (it->second == "inherit")
-					style.TextColor = current.TextColor;
-				else
-					scanHTMLColor(it->second.c_str(), style.TextColor);
-			else
-			if (it->first == "text-decoration" || it->first == "text-decoration-line")
-			{
-				std::string prop(toLower(it->second));
-				style.Underlined = (prop.find("underline") != std::string::npos);
-				style.StrikeThrough = (prop.find("line-through") != std::string::npos);
-			}
-			else
-			if (it->first == "text-stroke" || it->first == "-webkit-text-stroke")
-			{
-				// text-stroke: length || color
-				bool success = false;
-				uint px = 0;
-				CRGBA color;
-				std::vector<std::string> parts;
-				NLMISC::splitString(it->second, " ", parts);
-				if (parts.size() == 1)
-				{
-					success = scanCssLength(parts[0], px);
-					if (!success)
-						success = scanHTMLColor(parts[0].c_str(), color);
-				}
-				else if (parts.size() == 2)
-				{
-					success = scanCssLength(parts[0], px);
-					if (success)
-						success = scanHTMLColor(parts[1].c_str(), color);
-					else
-					{
-						success = scanHTMLColor(parts[0].c_str(), color);
-						success = success && scanCssLength(parts[1], px);
-					}
-				}
-
-				// do not disable shadow if one is already set
-				if (success)
-				{
-					style.TextShadow.Enabled = (px > 0);
-					style.TextShadow.Color = color;
-					style.TextShadow.X = px;
-					style.TextShadow.Y = px;
-					style.TextShadow.Outline = true;
-				}
-			}
-			else
-			if (it->first == "text-shadow")
-			{
-				if (it->second == "none")
-					style.TextShadow = STextShadow(false);
-				else
-				if (it->second == "inherit")
-					style.TextShadow = current.TextShadow;
-				else
-				{
-					// text-shadow: offset-x offset-y | blur | #color
-					// text-shadow: #color | offset-x offset-y
-					bool success = true;
-					std::string prop(it->second);
-					size_t pos;
-					pos = prop.find_first_of(",\n\r");
-					if (pos != std::string::npos)
-						prop = prop.substr(0, pos);
-
-					std::vector<std::string> parts;
-					NLMISC::splitString(prop, " ", parts);
-					switch(parts.size())
-					{
-						case 1:
-						{
-							success = scanHTMLColor(it->second.c_str(), style.TextShadow.Color);
-							break;
-						}
-						// no case 2:
-						case 3:
-						{
-							if (!fromString(parts[0], style.TextShadow.X))
-							{
-								success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
-								success = success && fromString(parts[1], style.TextShadow.X);
-								success = success && fromString(parts[2], style.TextShadow.Y);
-							}
-							else
-							{
-								success = fromString(parts[1], style.TextShadow.Y);
-								success = success && scanHTMLColor(parts[2].c_str(), style.TextShadow.Color);
-							}
-							break;
-						}
-						case 4:
-						{
-							if (!fromString(parts[0], style.TextShadow.X))
-							{
-								success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
-								success = success && fromString(parts[1], style.TextShadow.X);
-								success = success && fromString(parts[2], style.TextShadow.Y);
-								// ignore blur [3]
-							}
-							else
-							{
-								success = fromString(parts[0], style.TextShadow.X);
-								success = success && fromString(parts[1], style.TextShadow.Y);
-								// ignore blur [2]
-								success = success && scanHTMLColor(parts[3].c_str(), style.TextShadow.Color);
-							}
-							break;
-						}
-						default:
-						{
-							// unsupported rule
-							break;
-						}
-					}
-
-					style.TextShadow.Enabled = success;
-				}
-			}
-			else
-			if (it->first == "width")
-			{
-				std::string unit;
-				if (getCssLength(tmpf, unit, it->second.c_str()))
-				{
-					if (unit == "rem")
-						style.Width = tmpf * _StyleDefault.FontSize;
-					else if (unit == "em")
-						style.Width = tmpf * style.FontSize;
-					else if (unit == "pt")
-						style.FontSize = tmpf / 0.75f;
-					else
-						style.Width = tmpf;
-				}
-			}
-			else
-			if (it->first == "height")
-			{
-				std::string unit;
-				if (getCssLength(tmpf, unit, it->second.c_str()))
-				{
-					if (unit == "rem")
-						style.Height = tmpf * _StyleDefault.FontSize;
-					else if (unit == "em")
-						style.Height = tmpf * style.FontSize;
-					else if (unit == "pt")
-						style.FontSize = tmpf / 0.75f;
-					else
-						style.Height = tmpf;
-				}
-			}
-			else
-			if (it->first == "max-width")
-			{
-				std::string unit;
-				if (getCssLength(tmpf, unit, it->second.c_str()))
-				{
-					if (unit == "rem")
-						style.MaxWidth = tmpf * _StyleDefault.FontSize;
-					else if (unit == "em")
-						style.MaxWidth = tmpf * style.FontSize;
-					else if (unit == "pt")
-						style.FontSize = tmpf / 0.75f;
-					else
-						style.MaxWidth = tmpf;
-				}
-			}
-			else
-			if (it->first == "max-height")
-			{
-				std::string unit;
-				if (getCssLength(tmpf, unit, it->second.c_str()))
-				{
-					if (unit == "rem")
-						style.MaxHeight = tmpf * _StyleDefault.FontSize;
-					else if (unit == "em")
-						style.MaxHeight = tmpf * style.FontSize;
-					else if (unit == "pt")
-						style.FontSize = tmpf / 0.75f;
-					else
-						style.MaxHeight = tmpf;
-				}
-			}
-			else
-			if (it->first == "-ryzom-modulate-color")
-			{
-				bool b;
-				if (it->second == "inherit")
-					style.GlobalColor = current.GlobalColor;
-				else
-				if (fromString(it->second, b))
-					style.GlobalColor = b;
-			}
-			else
-			if (it->first == "background-color")
-			{
-				if (it->second == "inherit")
-					style.BackgroundColor = current.BackgroundColor;
-				else
-					scanHTMLColor(it->second.c_str(), style.BackgroundColor);
-			}
-			else
-			if (it->first == "-ryzom-background-color-over")
-			{
-				if (it->second == "inherit")
-					style.BackgroundColorOver = current.BackgroundColorOver;
-				else
-					scanHTMLColor(it->second.c_str(), style.BackgroundColorOver);
-			}
-		}
-
-		// if outer element has underline set, then inner element cannot remove it
-		if (current.Underlined)
-			style.Underlined = current.Underlined;
-
-		// if outer element has line-through set, then inner element cannot remove it
-		if (current.StrikeThrough)
-			style.StrikeThrough = current.StrikeThrough;
-	}
-
-	// ***************************************************************************
-	void CGroupHTML::applyCssMinMax(sint32 &width, sint32 &height, sint32 minw, sint32 minh, sint32 maxw, sint32 maxh)
-	{
-		if (maxw <= 0) maxw = width;
-		if (maxh <= 0) maxh = height;
-
-		maxw = std::max(minw, maxw);
-		maxh = std::max(minh, maxh);
-		
-		float ratio = (float) width / std::max(1, height);
-		if (width > maxw)
-		{
-			width = maxw;
-			height = std::max((sint32)(maxw /ratio), minh);
-		}
-		if (width < minw)
-		{
-			width = minw;
-			height = std::min((sint32)(minw / ratio), maxh);
-		}
-		if (height > maxh)
-		{
-			width = std::max((sint32)(maxh * ratio), minw);
-			height = maxh;
-		}
-		if (height < minh)
-		{
-			width = std::min((sint32)(minh * ratio), maxw);
-			height = minh;
-		}
-		if (width > maxw && height > maxh)
-		{
-			if (maxw/width <= maxh/height)
-			{
-				width = maxw;
-				height = std::max(minh, (sint32)(maxw / ratio));
-			}
-			else
-			{
-				width = std::max(minw, (sint32)(maxh * ratio));
-				height = maxh;
-			}
-		}
-		if (width < minw && height < minh)
-		{
-			if (minw / width <= minh / height)
-			{
-				width = std::min(maxw, (sint32)(minh * ratio));
-				height = minh;
-			}
-			else
-			{
-				width = minw;
-				height = std::min(maxh, (sint32)(minw / ratio));
-			}
-		}
-		if (width < minw && height > maxh)
-		{
-			width = minw;
-			height = maxh;
-		}
-		if (width > maxw && height < minh)
-		{
-			width = maxw;
-			height = minh;
-		}
+		_Style.reset();
+		_Style.Root.TextColor = TextColor;
+		_Style.Root.FontSize = TextFontSize;
+		_Style.Root.BackgroundColor = BgColor;
+		_Style.Current = _Style.Root;
 	}
 	
 	// ***************************************************************************
diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp
index ca8920b14..50cac24bf 100644
--- a/code/nel/src/gui/libwww.cpp
+++ b/code/nel/src/gui/libwww.cpp
@@ -345,6 +345,368 @@ namespace NLGUI
 		}
 	}
 
+	static bool isHexa(char c)
+	{
+		return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f');
+	}
+
+	static uint8 convertHexa(char c)
+	{
+		return (uint8) (tolower(c) - (isdigit(c) ? '0' : ('a' - 10)));
+	}
+
+	// scan a color component, and return pointer to next position
+	static const char *scanColorComponent(const char *src, uint8 &intensity)
+	{
+		if (!src) return NULL;
+		if (!isHexa(*src)) return NULL;
+		uint8 value = convertHexa(*src++) << 4;
+		if (!isHexa(*src)) return NULL;
+		value += convertHexa(*src++);
+		intensity = value;
+		return src;
+	}
+
+	static float hueToRgb(float m1, float m2, float h)
+	{
+		if (h < 0) h += 1.0f;
+		if (h > 1) h -= 1.0f;
+		if (h*6 < 1.0f) return m1 + (m2 - m1)*h*6;
+		if (h*2 < 1.0f) return m2;
+		if (h*3 < 2.0f) return m1 + (m2 - m1) * (2.0f/3.0f - h)*6;
+		return m1;
+	}
+
+	static void hslToRgb(float h, float s, float l, CRGBA &result)
+	{
+		float m1, m2;
+		if (l <= 0.5f)
+			m2 = l * (s + 1.0f);
+		else
+			m2 = l + s - l * s;
+		m1 = l*2 - m2;
+
+		result.R = 255 * hueToRgb(m1, m2, h + 1.0f/3.0f);
+		result.G = 255 * hueToRgb(m1, m2, h);
+		result.B = 255 * hueToRgb(m1, m2, h - 1.0f/3.0f);
+		result.A = 255;
+	}
+
+	class CNameToCol
+	{
+	public:
+		const char *Name;
+		CRGBA Color;
+		CNameToCol(const char *name, CRGBA color) : Name(name), Color(color) {}
+	};
+
+	static CNameToCol htmlColorNameToRGBA[] =
+	{
+		CNameToCol("AliceBlue", CRGBA(0xF0, 0xF8, 0xFF)),
+		CNameToCol("AntiqueWhite", CRGBA(0xFA, 0xEB, 0xD7)),
+		CNameToCol("Aqua", CRGBA(0x00, 0xFF, 0xFF)),
+		CNameToCol("Aquamarine", CRGBA(0x7F, 0xFF, 0xD4)),
+		CNameToCol("Azure", CRGBA(0xF0, 0xFF, 0xFF)),
+		CNameToCol("Beige", CRGBA(0xF5, 0xF5, 0xDC)),
+		CNameToCol("Bisque", CRGBA(0xFF, 0xE4, 0xC4)),
+		CNameToCol("Black", CRGBA(0x00, 0x00, 0x00)),
+		CNameToCol("BlanchedAlmond", CRGBA(0xFF, 0xEB, 0xCD)),
+		CNameToCol("Blue", CRGBA(0x00, 0x00, 0xFF)),
+		CNameToCol("BlueViolet", CRGBA(0x8A, 0x2B, 0xE2)),
+		CNameToCol("Brown", CRGBA(0xA5, 0x2A, 0x2A)),
+		CNameToCol("BurlyWood", CRGBA(0xDE, 0xB8, 0x87)),
+		CNameToCol("CadetBlue", CRGBA(0x5F, 0x9E, 0xA0)),
+		CNameToCol("Chartreuse", CRGBA(0x7F, 0xFF, 0x00)),
+		CNameToCol("Chocolate", CRGBA(0xD2, 0x69, 0x1E)),
+		CNameToCol("Coral", CRGBA(0xFF, 0x7F, 0x50)),
+		CNameToCol("CornflowerBlue", CRGBA(0x64, 0x95, 0xED)),
+		CNameToCol("Cornsilk", CRGBA(0xFF, 0xF8, 0xDC)),
+		CNameToCol("Crimson", CRGBA(0xDC, 0x14, 0x3C)),
+		CNameToCol("Cyan", CRGBA(0x00, 0xFF, 0xFF)),
+		CNameToCol("DarkBlue", CRGBA(0x00, 0x00, 0x8B)),
+		CNameToCol("DarkCyan", CRGBA(0x00, 0x8B, 0x8B)),
+		CNameToCol("DarkGoldenRod", CRGBA(0xB8, 0x86, 0x0B)),
+		CNameToCol("DarkGray", CRGBA(0xA9, 0xA9, 0xA9)),
+		CNameToCol("DarkGreen", CRGBA(0x00, 0x64, 0x00)),
+		CNameToCol("DarkKhaki", CRGBA(0xBD, 0xB7, 0x6B)),
+		CNameToCol("DarkMagenta", CRGBA(0x8B, 0x00, 0x8B)),
+		CNameToCol("DarkOliveGreen", CRGBA(0x55, 0x6B, 0x2F)),
+		CNameToCol("Darkorange", CRGBA(0xFF, 0x8C, 0x00)),
+		CNameToCol("DarkOrchid", CRGBA(0x99, 0x32, 0xCC)),
+		CNameToCol("DarkRed", CRGBA(0x8B, 0x00, 0x00)),
+		CNameToCol("DarkSalmon", CRGBA(0xE9, 0x96, 0x7A)),
+		CNameToCol("DarkSeaGreen", CRGBA(0x8F, 0xBC, 0x8F)),
+		CNameToCol("DarkSlateBlue", CRGBA(0x48, 0x3D, 0x8B)),
+		CNameToCol("DarkSlateGray", CRGBA(0x2F, 0x4F, 0x4F)),
+		CNameToCol("DarkTurquoise", CRGBA(0x00, 0xCE, 0xD1)),
+		CNameToCol("DarkViolet", CRGBA(0x94, 0x00, 0xD3)),
+		CNameToCol("DeepPink", CRGBA(0xFF, 0x14, 0x93)),
+		CNameToCol("DeepSkyBlue", CRGBA(0x00, 0xBF, 0xFF)),
+		CNameToCol("DimGray", CRGBA(0x69, 0x69, 0x69)),
+		CNameToCol("DodgerBlue", CRGBA(0x1E, 0x90, 0xFF)),
+		CNameToCol("Feldspar", CRGBA(0xD1, 0x92, 0x75)),
+		CNameToCol("FireBrick", CRGBA(0xB2, 0x22, 0x22)),
+		CNameToCol("FloralWhite", CRGBA(0xFF, 0xFA, 0xF0)),
+		CNameToCol("ForestGreen", CRGBA(0x22, 0x8B, 0x22)),
+		CNameToCol("Fuchsia", CRGBA(0xFF, 0x00, 0xFF)),
+		CNameToCol("Gainsboro", CRGBA(0xDC, 0xDC, 0xDC)),
+		CNameToCol("GhostWhite", CRGBA(0xF8, 0xF8, 0xFF)),
+		CNameToCol("Gold", CRGBA(0xFF, 0xD7, 0x00)),
+		CNameToCol("GoldenRod", CRGBA(0xDA, 0xA5, 0x20)),
+		CNameToCol("Gray", CRGBA(0x80, 0x80, 0x80)),
+		CNameToCol("Green", CRGBA(0x00, 0x80, 0x00)),
+		CNameToCol("GreenYellow", CRGBA(0xAD, 0xFF, 0x2F)),
+		CNameToCol("HoneyDew", CRGBA(0xF0, 0xFF, 0xF0)),
+		CNameToCol("HotPink", CRGBA(0xFF, 0x69, 0xB4)),
+		CNameToCol("IndianRed ", CRGBA(0xCD, 0x5C, 0x5C)),
+		CNameToCol("Indigo  ", CRGBA(0x4B, 0x00, 0x82)),
+		CNameToCol("Ivory", CRGBA(0xFF, 0xFF, 0xF0)),
+		CNameToCol("Khaki", CRGBA(0xF0, 0xE6, 0x8C)),
+		CNameToCol("Lavender", CRGBA(0xE6, 0xE6, 0xFA)),
+		CNameToCol("LavenderBlush", CRGBA(0xFF, 0xF0, 0xF5)),
+		CNameToCol("LawnGreen", CRGBA(0x7C, 0xFC, 0x00)),
+		CNameToCol("LemonChiffon", CRGBA(0xFF, 0xFA, 0xCD)),
+		CNameToCol("LightBlue", CRGBA(0xAD, 0xD8, 0xE6)),
+		CNameToCol("LightCoral", CRGBA(0xF0, 0x80, 0x80)),
+		CNameToCol("LightCyan", CRGBA(0xE0, 0xFF, 0xFF)),
+		CNameToCol("LightGoldenRodYellow", CRGBA(0xFA, 0xFA, 0xD2)),
+		CNameToCol("LightGrey", CRGBA(0xD3, 0xD3, 0xD3)),
+		CNameToCol("LightGreen", CRGBA(0x90, 0xEE, 0x90)),
+		CNameToCol("LightPink", CRGBA(0xFF, 0xB6, 0xC1)),
+		CNameToCol("LightSalmon", CRGBA(0xFF, 0xA0, 0x7A)),
+		CNameToCol("LightSeaGreen", CRGBA(0x20, 0xB2, 0xAA)),
+		CNameToCol("LightSkyBlue", CRGBA(0x87, 0xCE, 0xFA)),
+		CNameToCol("LightSlateBlue", CRGBA(0x84, 0x70, 0xFF)),
+		CNameToCol("LightSlateGray", CRGBA(0x77, 0x88, 0x99)),
+		CNameToCol("LightSteelBlue", CRGBA(0xB0, 0xC4, 0xDE)),
+		CNameToCol("LightYellow", CRGBA(0xFF, 0xFF, 0xE0)),
+		CNameToCol("Lime", CRGBA(0x00, 0xFF, 0x00)),
+		CNameToCol("LimeGreen", CRGBA(0x32, 0xCD, 0x32)),
+		CNameToCol("Linen", CRGBA(0xFA, 0xF0, 0xE6)),
+		CNameToCol("Magenta", CRGBA(0xFF, 0x00, 0xFF)),
+		CNameToCol("Maroon", CRGBA(0x80, 0x00, 0x00)),
+		CNameToCol("MediumAquaMarine", CRGBA(0x66, 0xCD, 0xAA)),
+		CNameToCol("MediumBlue", CRGBA(0x00, 0x00, 0xCD)),
+		CNameToCol("MediumOrchid", CRGBA(0xBA, 0x55, 0xD3)),
+		CNameToCol("MediumPurple", CRGBA(0x93, 0x70, 0xD8)),
+		CNameToCol("MediumSeaGreen", CRGBA(0x3C, 0xB3, 0x71)),
+		CNameToCol("MediumSlateBlue", CRGBA(0x7B, 0x68, 0xEE)),
+		CNameToCol("MediumSpringGreen", CRGBA(0x00, 0xFA, 0x9A)),
+		CNameToCol("MediumTurquoise", CRGBA(0x48, 0xD1, 0xCC)),
+		CNameToCol("MediumVioletRed", CRGBA(0xC7, 0x15, 0x85)),
+		CNameToCol("MidnightBlue", CRGBA(0x19, 0x19, 0x70)),
+		CNameToCol("MintCream", CRGBA(0xF5, 0xFF, 0xFA)),
+		CNameToCol("MistyRose", CRGBA(0xFF, 0xE4, 0xE1)),
+		CNameToCol("Moccasin", CRGBA(0xFF, 0xE4, 0xB5)),
+		CNameToCol("NavajoWhite", CRGBA(0xFF, 0xDE, 0xAD)),
+		CNameToCol("Navy", CRGBA(0x00, 0x00, 0x80)),
+		CNameToCol("OldLace", CRGBA(0xFD, 0xF5, 0xE6)),
+		CNameToCol("Olive", CRGBA(0x80, 0x80, 0x00)),
+		CNameToCol("OliveDrab", CRGBA(0x6B, 0x8E, 0x23)),
+		CNameToCol("Orange", CRGBA(0xFF, 0xA5, 0x00)),
+		CNameToCol("OrangeRed", CRGBA(0xFF, 0x45, 0x00)),
+		CNameToCol("Orchid", CRGBA(0xDA, 0x70, 0xD6)),
+		CNameToCol("PaleGoldenRod", CRGBA(0xEE, 0xE8, 0xAA)),
+		CNameToCol("PaleGreen", CRGBA(0x98, 0xFB, 0x98)),
+		CNameToCol("PaleTurquoise", CRGBA(0xAF, 0xEE, 0xEE)),
+		CNameToCol("PaleVioletRed", CRGBA(0xD8, 0x70, 0x93)),
+		CNameToCol("PapayaWhip", CRGBA(0xFF, 0xEF, 0xD5)),
+		CNameToCol("PeachPuff", CRGBA(0xFF, 0xDA, 0xB9)),
+		CNameToCol("Peru", CRGBA(0xCD, 0x85, 0x3F)),
+		CNameToCol("Pink", CRGBA(0xFF, 0xC0, 0xCB)),
+		CNameToCol("Plum", CRGBA(0xDD, 0xA0, 0xDD)),
+		CNameToCol("PowderBlue", CRGBA(0xB0, 0xE0, 0xE6)),
+		CNameToCol("Purple", CRGBA(0x80, 0x00, 0x80)),
+		CNameToCol("Red", CRGBA(0xFF, 0x00, 0x00)),
+		CNameToCol("RosyBrown", CRGBA(0xBC, 0x8F, 0x8F)),
+		CNameToCol("RoyalBlue", CRGBA(0x41, 0x69, 0xE1)),
+		CNameToCol("SaddleBrown", CRGBA(0x8B, 0x45, 0x13)),
+		CNameToCol("Salmon", CRGBA(0xFA, 0x80, 0x72)),
+		CNameToCol("SandyBrown", CRGBA(0xF4, 0xA4, 0x60)),
+		CNameToCol("SeaGreen", CRGBA(0x2E, 0x8B, 0x57)),
+		CNameToCol("SeaShell", CRGBA(0xFF, 0xF5, 0xEE)),
+		CNameToCol("Sienna", CRGBA(0xA0, 0x52, 0x2D)),
+		CNameToCol("Silver", CRGBA(0xC0, 0xC0, 0xC0)),
+		CNameToCol("SkyBlue", CRGBA(0x87, 0xCE, 0xEB)),
+		CNameToCol("SlateBlue", CRGBA(0x6A, 0x5A, 0xCD)),
+		CNameToCol("SlateGray", CRGBA(0x70, 0x80, 0x90)),
+		CNameToCol("Snow", CRGBA(0xFF, 0xFA, 0xFA)),
+		CNameToCol("SpringGreen", CRGBA(0x00, 0xFF, 0x7F)),
+		CNameToCol("SteelBlue", CRGBA(0x46, 0x82, 0xB4)),
+		CNameToCol("Tan", CRGBA(0xD2, 0xB4, 0x8C)),
+		CNameToCol("Teal", CRGBA(0x00, 0x80, 0x80)),
+		CNameToCol("Thistle", CRGBA(0xD8, 0xBF, 0xD8)),
+		CNameToCol("Tomato", CRGBA(0xFF, 0x63, 0x47)),
+		CNameToCol("Turquoise", CRGBA(0x40, 0xE0, 0xD0)),
+		CNameToCol("Violet", CRGBA(0xEE, 0x82, 0xEE)),
+		CNameToCol("VioletRed", CRGBA(0xD0, 0x20, 0x90)),
+		CNameToCol("Wheat", CRGBA(0xF5, 0xDE, 0xB3)),
+		CNameToCol("White", CRGBA(0xFF, 0xFF, 0xFF)),
+		CNameToCol("WhiteSmoke", CRGBA(0xF5, 0xF5, 0xF5)),
+		CNameToCol("Yellow", CRGBA(0xFF, 0xFF, 0x00)),
+		CNameToCol("YellowGreen", CRGBA(0x9A, 0xCD, 0x32))
+	};
+
+	// scan a color from a HTML form (#rrggbb format)
+	bool scanHTMLColor(const char *src, CRGBA &dest)
+	{
+		if (!src || *src == '\0') return false;
+		if (*src == '#')
+		{
+			++src;
+			if (strlen(src) == 3 || strlen(src) == 4)
+			{
+				bool hasAlpha = (strlen(src) == 4);
+				// check RGB for valid hex
+				if (isHexa(src[0]) && isHexa(src[1]) && isHexa(src[2]))
+				{
+					// check optional A for valid hex
+					if (hasAlpha && !isHexa(src[3])) return false;
+
+					dest.R = convertHexa(src[0]);
+					dest.G = convertHexa(src[1]);
+					dest.B = convertHexa(src[2]);
+
+					dest.R = dest.R << 4 | dest.R;
+					dest.G = dest.G << 4 | dest.G;
+					dest.B = dest.B << 4 | dest.B;
+
+					if (hasAlpha)
+					{
+						dest.A = convertHexa(src[3]);
+						dest.A = dest.A << 4 | dest.A;
+					}
+					else
+						dest.A = 255;
+
+					return true;
+				}
+
+				return false;
+			}
+
+			CRGBA result;
+			src = scanColorComponent(src, result.R); if (!src) return false;
+			src = scanColorComponent(src, result.G); if (!src) return false;
+			src = scanColorComponent(src, result.B); if (!src) return false;
+			src = scanColorComponent(src, result.A);
+			if (!src)
+			{
+				// Alpha is optional
+				result.A = 255;
+			}
+			dest = result;
+			return true;
+		}
+
+		if (strnicmp(src, "rgb(", 4) == 0 || strnicmp(src, "rgba(", 5) == 0)
+		{
+			src += 4;
+			if (*src == '(') src++;
+
+			std::vector<std::string> parts;
+			NLMISC::splitString(src, ",", parts);
+			if (parts.size() >= 3)
+			{
+				CRGBA result;
+				sint tmpv;
+				float tmpf;
+
+				// R
+				if (getPercentage(tmpv, tmpf, parts[0].c_str())) tmpv = 255 * tmpf;
+				clamp(tmpv, 0, 255);
+				result.R = tmpv;
+
+				// G
+				if (getPercentage(tmpv, tmpf, parts[1].c_str())) tmpv = 255 * tmpf;
+				clamp(tmpv, 0, 255);
+				result.G = tmpv;
+
+				// B
+				if (getPercentage(tmpv, tmpf, parts[2].c_str())) tmpv = 255 * tmpf;
+				clamp(tmpv, 0, 255);
+				result.B = tmpv;
+
+				// A
+				if (parts.size() == 4)
+				{
+					if (!fromString(parts[3], tmpf)) return false;
+					if (parts[3].find_first_of("%") != std::string::npos)
+						tmpf /= 100;
+
+					tmpv = 255 * tmpf;
+					clamp(tmpv, 0, 255);
+					result.A = tmpv;
+				}
+				else
+					result.A = 255;
+
+				dest = result;
+				return true;
+			}
+
+			return false;
+		}
+
+		if (strnicmp(src, "hsl(", 4) == 0 || strnicmp(src, "hsla(", 5) == 0)
+		{
+			src += 4;
+			if (*src == '(') src++;
+
+			std::vector<std::string> parts;
+			NLMISC::splitString(src, ",", parts);
+			if (parts.size() >= 3)
+			{
+				sint tmpv;
+				float h, s, l;
+				// hue
+				if (!fromString(parts[0], tmpv)) return false;
+				tmpv = ((tmpv % 360) + 360) % 360;
+				h = (float) tmpv / 360.0f;
+
+				// saturation
+				if (!getPercentage(tmpv, s, parts[1].c_str())) return false;
+				clamp(s, 0.0f, 1.0f);
+
+				// lightness
+				if (!getPercentage(tmpv, l, parts[2].c_str())) return false;
+				clamp(l, 0.0f, 1.0f);
+
+				CRGBA result;
+				hslToRgb(h, s, l, result);
+
+				// A
+				if (parts.size() == 4)
+				{
+					float tmpf;
+					if (!fromString(parts[3], tmpf)) return false;
+					if (parts[3].find_first_of("%") != std::string::npos)
+						tmpf /= 100;
+					clamp(tmpf, 0.0f, 1.0f);
+					result.A = 255 * tmpf;
+				}
+
+				dest = result;
+				return true;
+			}
+
+			return false;
+		}
+
+		{
+			// slow but should suffice for now
+			for(uint k = 0; k < sizeofarray(htmlColorNameToRGBA); ++k)
+			{
+				if (nlstricmp(src, htmlColorNameToRGBA[k].Name) == 0)
+				{
+					dest = htmlColorNameToRGBA[k].Color;
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+
 	// ***************************************************************************
 
 	CRGBA getColor (const char *color)

From aede4dbab7b9871772ed01ede1b361c2f6af174b Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Mon, 29 Apr 2019 15:03:55 +0300
Subject: [PATCH 06/75] Added: relative/absolute font size values for css

--HG--
branch : develop
---
 code/nel/src/gui/css_style.cpp | 35 ++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp
index 9d4b665bb..35d28717e 100644
--- a/code/nel/src/gui/css_style.cpp
+++ b/code/nel/src/gui/css_style.cpp
@@ -114,6 +114,41 @@ namespace NLGUI
 				{
 					style.FontSize = current.FontSize;
 				}
+				else if (it->second == "x-small")
+				{
+					style.FontSize = 10; // 62.5%
+				}
+				else if (it->second == "small")
+				{
+					style.FontSize = 13; // 80%;
+				}
+				else if (it->second == "medium")
+				{
+					style.FontSize = 16; // 100%;
+				}
+				else if (it->second == "large")
+				{
+					style.FontSize = 18; // 112.5%
+				}
+				else if (it->second == "x-large")
+				{
+					style.FontSize = 24; // 150%
+				}
+				else if (it->second == "xx-large")
+				{
+					style.FontSize = 32; // 200%;
+				}
+				else if (it->second == "smaller")
+				{
+					if (style.FontSize < 5)
+						style.FontSize = 3;
+					else
+						style.FontSize -= 2;
+				}
+				else if (it->second == "larger")
+				{
+					style.FontSize += 2;
+				}
 				else
 				{
 					std::string unit;

From 9587e9bcefbe4182d542e1e163ade517b25da705 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Mon, 29 Apr 2019 15:03:55 +0300
Subject: [PATCH 07/75] Added: transparent, currentcolor values for
 background-color

--HG--
branch : develop
---
 code/nel/src/gui/css_style.cpp | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp
index 35d28717e..8fc1207d2 100644
--- a/code/nel/src/gui/css_style.cpp
+++ b/code/nel/src/gui/css_style.cpp
@@ -95,8 +95,21 @@ namespace NLGUI
 		TStyle::iterator it;
 
 		// first pass: get font-size for 'em' sizes
+		// get TextColor value used as 'currentcolor'
 		for (it=styles.begin(); it != styles.end(); ++it)
 		{
+			if (it->first == "color")
+			{
+				if (it->second == "inherit")
+				{
+					style.TextColor = current.TextColor;
+				}
+				else
+				{
+					scanHTMLColor(it->second.c_str(), style.TextColor);
+				}
+			}
+			else
 			if (it->first == "font")
 			{
 				if (it->second == "inherit")
@@ -237,12 +250,6 @@ namespace NLGUI
 				style.FontWeight = weight;
 			}
 			else
-			if (it->first == "color")
-				if (it->second == "inherit")
-					style.TextColor = current.TextColor;
-				else
-					scanHTMLColor(it->second.c_str(), style.TextColor);
-			else
 			if (it->first == "text-decoration" || it->first == "text-decoration-line")
 			{
 				std::string prop(toLower(it->second));
@@ -437,6 +444,10 @@ namespace NLGUI
 			{
 				if (it->second == "inherit")
 					style.BackgroundColor = current.BackgroundColor;
+				else if (it->second == "transparent")
+					style.BackgroundColor = CRGBA(0, 0, 0, 0);
+				else if (it->second == "currentcolor")
+					style.BackgroundColorOver = style.TextColor;
 				else
 					scanHTMLColor(it->second.c_str(), style.BackgroundColor);
 			}
@@ -445,6 +456,10 @@ namespace NLGUI
 			{
 				if (it->second == "inherit")
 					style.BackgroundColorOver = current.BackgroundColorOver;
+				else if (it->second == "transparent")
+					style.BackgroundColorOver = CRGBA(0, 0, 0, 0);
+				else if (it->second == "currentcolor")
+					style.BackgroundColorOver = style.TextColor;	
 				else
 					scanHTMLColor(it->second.c_str(), style.BackgroundColorOver);
 			}

From fb54672815daa322bcb8b76aed120ef3decb8769 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 5 Apr 2019 21:57:42 +0300
Subject: [PATCH 08/75] Changed: Implement HTML renderer with CSS styling

--HG--
branch : develop
---
 code/nel/include/nel/gui/css_parser.h         |  113 +-
 code/nel/include/nel/gui/css_selector.h       |  107 +
 code/nel/include/nel/gui/css_style.h          |   90 +-
 code/nel/include/nel/gui/group_html.h         |  125 +-
 code/nel/include/nel/gui/html_element.h       |   86 +
 code/nel/include/nel/gui/html_parser.h        |   20 +-
 code/nel/include/nel/gui/libwww.h             |    3 +
 code/nel/include/nel/misc/common.h            |   11 +
 code/nel/src/gui/css_parser.cpp               |  658 +++++
 code/nel/src/gui/css_selector.cpp             |  314 +++
 code/nel/src/gui/css_style.cpp                |  494 +++-
 code/nel/src/gui/group_html.cpp               | 2438 +++++++++++++++--
 code/nel/src/gui/html_element.cpp             |  168 ++
 code/nel/src/gui/html_parser.cpp              |  188 +-
 code/nel/src/gui/libwww.cpp                   |   10 +
 code/nel/src/gui/libwww_types.cpp             |    2 +
 .../src/interface_v3/group_quick_help.cpp     |   58 +-
 .../src/interface_v3/group_quick_help.h       |    3 +-
 18 files changed, 4587 insertions(+), 301 deletions(-)
 create mode 100644 code/nel/include/nel/gui/css_selector.h
 create mode 100644 code/nel/include/nel/gui/html_element.h
 create mode 100644 code/nel/src/gui/css_selector.cpp
 create mode 100644 code/nel/src/gui/html_element.cpp

diff --git a/code/nel/include/nel/gui/css_parser.h b/code/nel/include/nel/gui/css_parser.h
index cb4cea62e..cfaf03caa 100644
--- a/code/nel/include/nel/gui/css_parser.h
+++ b/code/nel/include/nel/gui/css_parser.h
@@ -19,6 +19,7 @@
 
 #include "nel/misc/types_nl.h"
 #include "nel/gui/css_style.h"
+#include "nel/gui/css_selector.h"
 
 namespace NLGUI
 {
@@ -31,8 +32,118 @@ namespace NLGUI
 	public:
 		// parse style declaration, eg "color: red; font-size: 10px;"
 		static TStyle parseDecls(const std::string &styleString);
-	};
 
+		// parse css stylesheet
+		void parseStylesheet(const std::string &cssString, std::vector<CCssStyle::SStyleRule> &rules);
+
+	private:
+		// stylesheet currently parsed
+		ucstring _Style;
+		// keep track of current position in _Style
+		size_t _Position;
+
+		std::vector<CCssStyle::SStyleRule> _Rules;
+
+	private:
+		// @media ( .. ) { .. }
+		void readAtRule();
+
+		// a#id.class[attr=val] { .. }
+		void readRule();
+
+		// move past whitespace
+		void skipWhitespace();
+
+		// skip valid IDENT
+		bool skipIdentifier();
+
+		// skip over {}, (), or [] block
+		void skipBlock();
+
+		// skip over string quoted with ' or "
+		void skipString();
+
+		// backslash escape
+		void escape();
+
+		// normalize newline chars and remove comments
+		void preprocess();
+
+		// parse selectors + combinators
+		std::vector<CCssSelector> parse_selector(const ucstring &sel, std::string &pseudoElement) const;
+
+		// parse selector and style
+		void parseRule(const ucstring &selectorString, const ucstring &styleString);
+
+		inline bool is_eof() const
+		{
+			return _Position >= _Style.size();
+		}
+
+		inline bool is_whitespace(ucchar ch) const
+		{
+			return (ch == (ucchar)' ' || ch == (ucchar)'\t' || ch == (ucchar)'\n');
+		}
+
+		inline bool is_hex(ucchar ch) const
+		{
+			return ((ch >= (ucchar)'0' && ch <= (ucchar)'9') ||
+					(ch >= (ucchar)'a' && ch <= (ucchar)'f') ||
+					(ch >= (ucchar)'A' && ch <= (ucchar)'F'));
+		}
+
+		inline bool maybe_escape() const
+		{
+			// escaping newline (\n) only allowed inside strings
+			return (_Style.size() - _Position) >= 1 && _Style[_Position] == (ucchar)'\\' && _Style[_Position+1] != '\n';
+		}
+
+		inline bool is_quote(ucchar ch) const
+		{
+			return	ch== (ucchar)'"' || ch == (ucchar)'\'';
+		}
+
+		inline bool is_block_open(ucchar ch) const
+		{
+			return	ch == (ucchar)'{' || ch == (ucchar)'[' || ch == (ucchar)'(';
+		}
+
+		inline bool is_block_close(ucchar ch, ucchar open) const
+		{
+			return ((open == '{' && ch == (ucchar)'}') ||
+					(open == '[' && ch == (ucchar)']') ||
+					(open == '(' && ch == (ucchar)')'));
+		}
+
+		inline bool is_comment_open() const
+		{
+			if (_Position+1 > _Style.size())
+				return false;
+
+			return _Style[_Position] == (ucchar)'/' && _Style[_Position+1] == (ucchar)'*';
+		}
+
+		inline bool is_nonascii(ucchar ch) const
+		{
+			return ch >= 0x80 /*&&  ch <= 255*/;
+		}
+
+		inline bool is_alpha(ucchar ch) const
+		{
+			return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
+		}
+
+		inline bool is_digit(ucchar ch) const
+		{
+			return ch >= '0' && ch <= '9';
+		}
+
+		inline bool is_nmchar(ucchar ch) const
+		{
+			// checking escape here does not check if next char is '\n' or not
+			return ch == '_' || ch == '-' || is_alpha(ch) || is_digit(ch) || is_nonascii(ch) || ch == '\\'/*is_escape(ch)*/;
+		}
+	};
 }//namespace
 
 #endif // CL_CSS_PARSER_H
diff --git a/code/nel/include/nel/gui/css_selector.h b/code/nel/include/nel/gui/css_selector.h
new file mode 100644
index 000000000..84b039089
--- /dev/null
+++ b/code/nel/include/nel/gui/css_selector.h
@@ -0,0 +1,107 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef CL_CSS_SELECTOR_H
+#define CL_CSS_SELECTOR_H
+
+#include "nel/misc/types_nl.h"
+
+namespace NLGUI
+{
+	class CHtmlElement;
+
+	/**
+	 * \brief CSS selector
+	 * \date 2019-03-15 10:50 GMT
+	 * \author Meelis Mägi (Nimetu)
+	 */
+	class CCssSelector
+	{
+	public:
+		enum ECombinator {
+			NONE = 0,
+			GENERAL_CHILD,
+			ADJACENT_SIBLING,
+			GENERAL_SIBLING,
+			CHILD_OF
+		};
+
+		struct SAttribute {
+			std::string key;
+			std::string value;
+			char op; // =, ~, |, ^, $, *
+			SAttribute(const std::string &k, const std::string &v, char o)
+				:key(k),value(v),op(o)
+			{}
+		};
+
+		std::string Element;
+		std::string Id;
+		std::vector<std::string> Class;
+		std::vector<SAttribute> Attr;
+		std::vector<std::string> PseudoClass;
+
+		// css combinator or \0 missing (first element)
+		char Combinator;
+
+	public:
+		// TODO: rewrite for ECombinator enum
+		CCssSelector(std::string elm="", std::string id="", std::string cls="", char comb = '\0');
+
+		// helper for sorting
+		uint32 specificity() const;
+
+		// set classes used, eg 'class1 class2'
+		void setClass(const std::string &cls);
+
+		// add attribute to selector
+		// ' ' op means 'key exists, ignore value'
+		void addAttribute(const std::string &key, const std::string &val = "", char op = ' ');
+
+		// add pseudo class to selector, eg 'first-child'
+		void addPseudoClass(const std::string &key);
+
+		// true if no rules have been defined
+		bool empty() const
+		{
+			return Element.empty() && Id.empty() && Class.empty() && Attr.empty() && PseudoClass.empty();
+		}
+
+		// Test current selector to html DOM element
+		// NOTE: Does not check combinator
+		bool match(const CHtmlElement &elm) const;
+
+	private:
+		bool matchClass(const CHtmlElement &elm) const;
+		bool matchAttributes(const CHtmlElement &elm) const;
+		bool matchPseudoClass(const CHtmlElement &elm) const;
+
+		// match An+B rule to child index (1 based)
+		bool matchNth(sint childNr, sint a, sint b) const;
+		
+		// parse nth-child string to 'a' and 'b' components
+		// :nth-child(odd)
+		// :nth-child(even)
+		// :nth-child(An+B)
+		// :nth-child(-An+b)
+		void parseNth(const std::string &pseudo, sint &a, sint &b) const;
+
+	};
+
+}//namespace
+
+#endif // CL_CSS_SELECTOR_H
+
diff --git a/code/nel/include/nel/gui/css_style.h b/code/nel/include/nel/gui/css_style.h
index 2a854a6d9..dea4a1f43 100644
--- a/code/nel/include/nel/gui/css_style.h
+++ b/code/nel/include/nel/gui/css_style.h
@@ -19,9 +19,12 @@
 
 #include "nel/misc/types_nl.h"
 #include "nel/misc/rgba.h"
+#include "nel/gui/css_selector.h"
 
 namespace NLGUI
 {
+	class CHtmlElement;
+
 	typedef std::map<std::string, std::string> TStyle;
 
 	/**
@@ -44,7 +47,7 @@ namespace NLGUI
 			sint32 X;
 			sint32 Y;
 			NLMISC::CRGBA Color;
-		};
+		};		
 	public:
 		CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
 		{
@@ -62,6 +65,19 @@ namespace NLGUI
 			BackgroundColor=NLMISC::CRGBA::Black;
 			BackgroundColorOver=NLMISC::CRGBA::Black;
 		}
+
+		bool hasStyle(const std::string &key) const
+		{
+			return StyleRules.find(key) != StyleRules.end();
+		}
+
+		std::string getStyle(const std::string &key) const
+		{
+			TStyle::const_iterator it = StyleRules.find(key);
+			return (it != StyleRules.end() ? it->second : "");
+		}
+
+	public:
 		uint FontSize;
 		uint FontWeight;
 		bool FontOblique;
@@ -78,11 +94,26 @@ namespace NLGUI
 		sint32 BorderWidth;
 		NLMISC::CRGBA BackgroundColor;
 		NLMISC::CRGBA BackgroundColorOver;
+
+		std::string WhiteSpace;
+		std::string TextAlign;
+		std::string VerticalAlign;
+
+		TStyle StyleRules;
 	};
 
 	class CCssStyle {
 	public:
+		struct SStyleRule {
+			std::vector<CCssSelector> Selector;
+			TStyle Properties;
 
+			// pseudo element like ':before'
+			std::string PseudoElement;
+			
+			// returns selector specificity
+			uint specificity() const;
+		};
 
 		// 'browser' style, overwriten with '<html>'
 		CStyleParams Root;
@@ -90,18 +121,37 @@ namespace NLGUI
 		// current element style
 		CStyleParams Current;
 
+		// known style rules sorted by specificity
+		std::vector<SStyleRule> _StyleRules;
+
 	private:
 		std::vector<CStyleParams> _StyleStack;
 
-		// test if str is one of "thin/medium/thick" and return its pixel value 
+		// test if str is one of "thin/medium/thick" and return its pixel value
 		bool scanCssLength(const std::string& str, uint32 &px) const;
 
 		// read style attribute
 		void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current) const;
+		void getStyleParams(const TStyle &styleRules, CStyleParams &style, const CStyleParams &current) const;
+
+		// merge src into dest by overwriting key in dest
+		void merge(TStyle &dst, const TStyle &src) const;
+
+		// match selector to dom path
+		bool match(const std::vector<CCssSelector> &selector, const CHtmlElement &elm) const;
+
+		// parse 'background' into 'background-color', 'background-image', etc
+		void parseBackgroundShorthand(const std::string &value, CStyleParams &style) const;
 
 	public:
 		void reset();
 
+		// parse <style>..</style> tag or css file content
+		void parseStylesheet(const std::string &styleString);
+
+		// set element style from matching css rules
+		void getStyleFor(CHtmlElement &elm) const;
+
 		inline uint getFontSizeSmaller() const
 		{
 			if (Current.FontSize < 5)
@@ -109,15 +159,29 @@ namespace NLGUI
 			return Current.FontSize-2;
 		}
 
+		sint styleStackIndex = 0;
+
 		inline void pushStyle()
 		{
+			styleStackIndex++;
 			_StyleStack.push_back(Current);
+
+			Current.Width=-1;
+			Current.Height=-1;
+			Current.MaxWidth=-1;
+			Current.MaxHeight=-1;
+			Current.BorderWidth=1;
+			
+			Current.StyleRules.clear();
 		}
 
 		inline void popStyle()
 		{
+			styleStackIndex--;
 			if (_StyleStack.empty())
+			{
 				Current = Root;
+			}
 			else
 			{
 				Current = _StyleStack.back();
@@ -125,16 +189,32 @@ namespace NLGUI
 			}
 		}
 
-		// apply style string to this.Root
+		// apply style to this.Root
 		void applyRootStyle(const std::string &styleString);
+		void applyRootStyle(const TStyle &styleRules);
 
-		// apply style string to this.Current
+		// apply style to this.Current
 		void applyStyle(const std::string &styleString);
+		void applyStyle(const TStyle &styleRules);
 
 		void applyCssMinMax(sint32 &width, sint32 &height, sint32 minw=0, sint32 minh=0, sint32 maxw=0, sint32 maxh=0) const;
 
-	};
+		// check if current style property matches value
+		bool checkStyle(const std::string &key, const std::string &val) const
+		{
+			return Current.hasStyle(key) && Current.getStyle(key) == val;
+		}
 
+		bool hasStyle(const std::string &key) const
+		{
+			return Current.hasStyle(key);
+		}
+
+		std::string getStyle(const std::string &key) const
+		{
+			return Current.getStyle(key);
+		}
+	};
 }//namespace
 
 #endif // CL_CSS_STYLE_H
diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index d8935f431..6a8760533 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -24,6 +24,7 @@
 #include "nel/gui/ctrl_button.h"
 #include "nel/gui/group_table.h"
 #include "nel/gui/libwww_types.h"
+#include "nel/gui/html_element.h"
 #include "nel/gui/css_style.h"
 
 // forward declaration
@@ -76,7 +77,7 @@ namespace NLGUI
 		static SWebOptions options;
 
 		// ImageDownload system
-		enum TDataType {ImgType= 0, BnpType};
+		enum TDataType {ImgType= 0, BnpType, StylesheetType};
 		enum TImageType {NormalImage=0, OverImage};
 		
 		// Constructor
@@ -97,6 +98,9 @@ namespace NLGUI
 		// Browse
 		virtual void browse (const char *url);
 
+		// load css from local file and insert into active stylesheet collection
+		void parseStylesheetFile(const std::string &fname);
+
 		// parse html string using libxml2 parser
 		bool parseHtml(const std::string &htmlString);
 
@@ -273,16 +277,10 @@ namespace NLGUI
 		virtual void addText (const char * buf, int len);
 
 		// A new begin HTML element has been parsed (<IMG> for exemple)
-		virtual void beginElement (uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value);
+		virtual void beginElement(CHtmlElement &elm);
 
 		// A new end HTML element has been parsed (</IMG> for exemple)
-		virtual void endElement (uint element_number);
-
-		// A new begin unparsed element has been found
-		virtual void beginUnparsedElement(const char *buffer, int length);
-
-		// A new end unparsed element has been found
-		virtual void endUnparsedElement(const char *buffer, int length);
+		virtual void endElement(CHtmlElement &elm);
 
 		// Add GET params to the url
 		virtual void addHTTPGetParams (std::string &url, bool trustedDomain);
@@ -296,6 +294,9 @@ namespace NLGUI
 		// Get Home URL
 		virtual std::string	home();
 
+		// parse dom node and all child nodes recursively
+		void renderDOM(CHtmlElement &elm);
+
 		// Clear style stack and restore default style
 		void resetCssStyle();
 
@@ -326,7 +327,7 @@ namespace NLGUI
 		void addString(const ucstring &str);
 
 		// Add an image in the current paragraph
-		void addImage(const std::string &id, const char *image, bool reloadImg=false, const CStyleParams &style = CStyleParams());
+		void addImage(const std::string &id, const std::string &img, bool reloadImg=false, const CStyleParams &style = CStyleParams());
 
 		// Add a text area in the current paragraph
 		CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content, uint maxlength);
@@ -365,6 +366,14 @@ namespace NLGUI
 		// Current URL
 		std::string		_DocumentUrl;
 		std::string		_DocumentDomain;
+        std::string		_DocumentHtml; // not updated, only set by first render
+		// If true, then render _DocumentHtml on next update (replaces content)
+		bool			_RenderNextTime;
+		// true if renderer is waiting for css files to finish downloading (link rel=stylesheet)
+		bool			_WaitingForStylesheet;
+		// list of css file urls that are queued up for download
+		std::vector<std::string> _StylesheetQueue;
+
 		// Valid base href was found
 		bool            _IgnoreBaseUrlTag;
 		// Fragment from loading url
@@ -484,6 +493,11 @@ namespace NLGUI
 
 		// Keep track of current element style
 		CCssStyle _Style;
+		CHtmlElement _HtmlDOM;
+		CHtmlElement *_CurrentHTMLElement;
+		// Backup of CurrentHTMLElement->nextSibling before ::beginElement() is called
+		// for luaParseHtml() to insert nodes into right place in right order
+		CHtmlElement *_CurrentHTMLNextSibling;
 
 		// Current link
 		std::vector<std::string>	_Link;
@@ -722,6 +736,12 @@ namespace NLGUI
 
 	private:
 		friend class CHtmlParser;
+		// TODO: beginElement is overwritten in client quick help class, merge it here?
+		void beginElementDeprecated(uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value);
+		void endElementDeprecated(uint element_number);
+
+		// move src->Children into CurrentHtmlElement.parent.children element
+		void spliceFragment(std::list<CHtmlElement>::iterator src);
 
 		// decode all HTML entities
 		static ucstring decodeHTMLEntities(const ucstring &str);
@@ -764,6 +784,8 @@ namespace NLGUI
 		int RunningCurls;
 
 		bool startCurlDownload(CDataDownload &download);
+		void finishCurlDownload(CDataDownload &download);
+		void pumpCurlDownloads();
 
 		void initImageDownload();
 		void checkImageDownload();
@@ -782,11 +804,94 @@ namespace NLGUI
 		bool addBnpDownload(std::string url, const std::string &action, const std::string &script, const std::string &md5sum);
 		std::string localBnpName(const std::string &url);
 
+		// add css file from <link href=".." rel="stylesheet"> to download queue
+		void addStylesheetDownload(std::vector<std::string> links);
+
 		void releaseDownloads();
 		void checkDownloads();
 
 		// HtmlType download finished
 		void htmlDownloadFinished(const std::string &content, const std::string &type, long code);
+
+		// stylesheet finished downloading. if local file does not exist, then it failed (404)
+		void cssDownloadFinished(const std::string &url, const std::string &local);
+
+		// read common table/tr/td parameters and push them to _CellParams
+		void getCellsParameters(const CHtmlElement &elm, bool inherit);
+
+		// render _HtmlDOM
+		void renderDocument();
+
+		// :before, :after rendering
+		void renderPseudoElement(const std::string &pseudo, const CHtmlElement &elm);
+
+		// HTML elements
+		void htmlA(const CHtmlElement &elm);
+		void htmlAend(const CHtmlElement &elm);
+		void htmlBASE(const CHtmlElement &elm);
+		void htmlBODY(const CHtmlElement &elm);
+		void htmlBR(const CHtmlElement &elm);
+		void htmlDD(const CHtmlElement &elm);
+		void htmlDDend(const CHtmlElement &elm);
+		//void htmlDEL(const CHtmlElement &elm);
+		void htmlDIV(const CHtmlElement &elm);
+		void htmlDIVend(const CHtmlElement &elm);
+		void htmlDL(const CHtmlElement &elm);
+		void htmlDLend(const CHtmlElement &elm);
+		void htmlDT(const CHtmlElement &elm);
+		void htmlDTend(const CHtmlElement &elm);
+		//void htmlEM(const CHtmlElement &elm);
+		void htmlFONT(const CHtmlElement &elm);
+		void htmlFORM(const CHtmlElement &elm);
+		void htmlH(const CHtmlElement &elm);
+		void htmlHend(const CHtmlElement &elm);
+		void htmlHEAD(const CHtmlElement &elm);
+		void htmlHEADend(const CHtmlElement &elm);
+		void htmlHR(const CHtmlElement &elm);
+		void htmlHTML(const CHtmlElement &elm);
+		void htmlI(const CHtmlElement &elm);
+		void htmlIend(const CHtmlElement &elm);
+		void htmlIMG(const CHtmlElement &elm);
+		void htmlINPUT(const CHtmlElement &elm);
+		void htmlLI(const CHtmlElement &elm);
+		void htmlLIend(const CHtmlElement &elm);
+		void htmlLUA(const CHtmlElement &elm);
+		void htmlLUAend(const CHtmlElement &elm);
+		void htmlMETA(const CHtmlElement &elm);
+		void htmlOBJECT(const CHtmlElement &elm);
+		void htmlOBJECTend(const CHtmlElement &elm);
+		void htmlOL(const CHtmlElement &elm);
+		void htmlOLend(const CHtmlElement &elm);
+		void htmlOPTION(const CHtmlElement &elm);
+		void htmlOPTIONend(const CHtmlElement &elm);
+		void htmlP(const CHtmlElement &elm);
+		void htmlPend(const CHtmlElement &elm);
+		void htmlPRE(const CHtmlElement &elm);
+		void htmlPREend(const CHtmlElement &elm);
+		void htmlSCRIPT(const CHtmlElement &elm);
+		void htmlSCRIPTend(const CHtmlElement &elm);
+		void htmlSELECT(const CHtmlElement &elm);
+		void htmlSELECTend(const CHtmlElement &elm);
+		//void htmlSMALL(const CHtmlElement &elm);
+		//void htmlSPAN(const CHtmlElement &elm);
+		//void htmlSTRONG(const CHtmlElement &elm);
+		void htmlSTYLE(const CHtmlElement &elm);
+		void htmlSTYLEend(const CHtmlElement &elm);
+		void htmlTABLE(const CHtmlElement &elm);
+		void htmlTABLEend(const CHtmlElement &elm);
+		void htmlTD(const CHtmlElement &elm);
+		void htmlTDend(const CHtmlElement &elm);
+		void htmlTEXTAREA(const CHtmlElement &elm);
+		void htmlTEXTAREAend(const CHtmlElement &elm);
+		void htmlTH(const CHtmlElement &elm);
+		void htmlTHend(const CHtmlElement &elm);
+		void htmlTITLE(const CHtmlElement &elm);
+		void htmlTITLEend(const CHtmlElement &elm);
+		void htmlTR(const CHtmlElement &elm);
+		void htmlTRend(const CHtmlElement &elm);
+		//void htmlU(const CHtmlElement &elm);
+		void htmlUL(const CHtmlElement &elm);
+		void htmlULend(const CHtmlElement &elm);
 	};
 
 	// adapter group that store y offset for inputs inside an html form
diff --git a/code/nel/include/nel/gui/html_element.h b/code/nel/include/nel/gui/html_element.h
new file mode 100644
index 000000000..bac681c1c
--- /dev/null
+++ b/code/nel/include/nel/gui/html_element.h
@@ -0,0 +1,86 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef CL_HTML_ELEMENT_H
+#define CL_HTML_ELEMENT_H
+
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_style.h"
+
+namespace NLGUI
+{
+	/**
+	 * \brief HTML element
+	 * \date 2019-04-25 18:23 GMT
+	 * \author Meelis Mägi (Nimetu)
+	 */
+	class CHtmlElement
+	{
+	public:
+		enum ENodeType {
+			NONE = 0,
+			ELEMENT_NODE = 1,
+			TEXT_NODE = 3,
+		};
+
+		uint ID; // libwww element enum
+		ENodeType Type;
+		std::string Value; // text node value or element node name
+		std::map<std::string, std::string> Attributes;
+		std::list<CHtmlElement> Children;
+
+		// class names for css matching
+		std::set<std::string> ClassNames;
+
+		// defined style and :before/:after pseudo elements
+		TStyle Style;
+		TStyle StyleBefore;
+		TStyle StyleAfter;
+
+		// hierarchy
+		CHtmlElement *parent;
+		CHtmlElement *previousSibling;
+		CHtmlElement *nextSibling;
+
+		// n'th ELEMENT_NODE in parent.Children, for :nth-child() rules
+		uint childIndex;
+
+		CHtmlElement(ENodeType type = NONE, std::string value = "");
+
+		// returns true if rhs is same pointer
+		friend bool operator==(const CHtmlElement &lhs, const CHtmlElement &rhs)
+		{
+			return &lhs == &rhs;
+		}
+
+		bool hasAttribute(const std::string &key) const;
+
+		bool hasNonEmptyAttribute(const std::string &key) const;
+
+		std::string getAttribute(const std::string &key) const;
+
+		bool hasClass(const std::string &key) const;
+
+		// update Children index/parent/next/prevSibling pointers
+		void reindexChilds();
+
+		// debug
+		std::string toString(bool tree = false, uint depth = 0) const;
+	};
+}
+
+#endif
+
diff --git a/code/nel/include/nel/gui/html_parser.h b/code/nel/include/nel/gui/html_parser.h
index 132c4ac88..760640234 100644
--- a/code/nel/include/nel/gui/html_parser.h
+++ b/code/nel/include/nel/gui/html_parser.h
@@ -21,7 +21,7 @@
 
 namespace NLGUI
 {
-	class CGroupHTML;
+	class CHtmlElement;
 
 	/**
 	 * \brief HTML parsing
@@ -31,21 +31,21 @@ namespace NLGUI
 	class CHtmlParser
 	{
 	public:
-		CHtmlParser(CGroupHTML *group) : _GroupHtml(group)
-		{}
+		bool parseHtml(std::string htmlString) const;
 
-		bool parseHtml(std::string htmlString);
+		// parse html string into DOM, extract <style> tags into styleString, <link stylesheet> urls into links
+		void getDOM(std::string htmlString, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const;
 
 	private:
-		// libxml2 html parser functions
-		void htmlElement(xmlNode *node, int element_number);
-		void parseNode(xmlNode *a_node);
+		// iterate over libxml html tree, build DOM, and join all <style> tags together
+		void parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const;
 
-	private:
+		// read <style> tag and add its content to styleString
+		void parseStyle(xmlNode *a_node, std::string &styleString) const;
 
-		CGroupHTML *_GroupHtml;
+		// update parent/sibling in elm.Children
+		void reindexChilds(CHtmlElement &elm) const;
 	};
-
 }
 
 #endif
diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h
index d7fe1251c..74227305c 100644
--- a/code/nel/include/nel/gui/libwww.h
+++ b/code/nel/include/nel/gui/libwww.h
@@ -297,6 +297,9 @@ namespace NLGUI
 	// Parse a HTML color
 	NLMISC::CRGBA getColor (const char *color);
 
+	// return css color in rgba() format
+	std::string getRGBAString(const NLMISC::CRGBA &color);
+
 	// ***************************************************************************
 
 	const std::string &setCurrentDomain(const std::string &uri);
diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index d5d59b130..a89ff226b 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -276,6 +276,17 @@ template <class T> T trimRightWhiteSpaces (const T &str)
 	return str.substr (0, end);
 }
 
+// if both first and last char are quotes (' or "), then remove them
+template <class T> T trimQuotes (const T&str)
+{
+	typename T::size_type size = str.size();
+	if (size == 0)
+		return str;
+	if (str[0] != str[size-1] && (str[0] != '"' || str[0] != '\''))
+		return str;
+	return str.substr(1, size - 1);
+}
+
 //////////////////////////////////////////////////////////////////////////
 // ****  DEPRECATED *****: PLEASE DON'T USE THESE METHODS BUT FUNCTIONS ABOVE toLower() and toUpper()
 //////////////////////////////////////////////////////////////////////////
diff --git a/code/nel/src/gui/css_parser.cpp b/code/nel/src/gui/css_parser.cpp
index c45121824..0a4288d12 100644
--- a/code/nel/src/gui/css_parser.cpp
+++ b/code/nel/src/gui/css_parser.cpp
@@ -20,6 +20,7 @@
 #include "nel/misc/types_nl.h"
 #include "nel/gui/css_parser.h"
 #include "nel/gui/css_style.h"
+#include "nel/gui/css_selector.h"
 
 using namespace NLMISC;
 
@@ -54,5 +55,662 @@ namespace NLGUI
 
 		return styles;
 	}
+
+	// ***************************************************************************
+	// Parse stylesheet, eg content from main.css file
+	//
+	// Return all found rules
+	void CCssParser::parseStylesheet(const std::string &cssString, std::vector<CCssStyle::SStyleRule> &result)
+	{
+		_Rules.clear();
+		_Style.clear();
+
+		_Style.fromUtf8(cssString);
+		preprocess();
+
+		_Position = 0;
+		while(!is_eof())
+		{
+			skipWhitespace();
+
+			if (_Style[_Position] == (ucchar)'@')
+				readAtRule();
+			else
+				readRule();
+		}
+
+		result.insert(result.end(), _Rules.begin(), _Rules.end());
+		_Rules.clear();
+	}
+
+	// ***************************************************************************
+	// Parse selector with style string
+	// selector: "a#id .class"
+	// style:    "color: red; font-size: 10px;"
+	//
+	// @internal
+	void CCssParser::parseRule(const ucstring &selectorString, const ucstring &styleString)
+	{
+		std::vector<ucstring> selectors;
+		NLMISC::explode(selectorString, ucstring(","), selectors);
+
+		TStyle props;
+		props = parseDecls(styleString.toUtf8());
+
+		// duplicate props to each selector in selector list,
+		// example 'div > p, h1' creates 'div>p' and 'h1'
+		for(uint i=0; i<selectors.size(); ++i)
+		{
+			CCssStyle::SStyleRule rule;
+
+			rule.Selector = parse_selector(trim(selectors[i]), rule.PseudoElement);
+			rule.Properties = props;
+
+			if (!rule.Selector.empty())
+			{
+				_Rules.push_back(rule);
+			}
+		}
+	}
+
+	// ***************************************************************************
+	// Skip over at-rule
+	// @import ... ;
+	// @charset ... ;
+	// @media query { .. }
+	//
+	// @internal
+	void CCssParser::readAtRule()
+	{
+		// skip '@'
+		_Position++;
+
+		// skip 'import', 'media', etc
+		skipIdentifier();
+
+		// skip at-rule statement
+		while(!is_eof() && _Style[_Position] != (ucchar)';')
+		{
+			if (maybe_escape())
+			{
+				escape();
+			}
+			else if (is_quote(_Style[_Position]))
+			{
+				skipString();
+			}
+			else if (is_block_open(_Style[_Position]))
+			{
+				bool mustBreak = (_Style[_Position] == '{');
+				skipBlock();
+
+				if(mustBreak)
+				{
+					break;
+				}
+			}
+			else
+			{
+				_Position++;
+			}
+		}
+
+		// skip ';' or '}'
+		_Position++;
+	}
+
+	// ***************************************************************************
+	// skip over "elm#id.selector[attr]:peseudo, .sel2 { rule }" block
+	// @internal
+	void CCssParser::readRule()
+	{
+		size_t start;
+
+		// selector
+		start = _Position;
+		while(!is_eof())
+		{
+			if (maybe_escape())
+				_Position++;
+			else if (is_quote(_Style[_Position]))
+				skipString();
+			else if (_Style[_Position] == (ucchar)'[')
+				skipBlock();
+			else if (_Style[_Position] == (ucchar)'{')
+				break;
+			else
+				_Position++;
+		}
+
+		if (!is_eof())
+		{
+			ucstring selector;
+			selector.append(_Style, start, _Position - start);
+
+			skipWhitespace();
+
+			// declaration block
+			start = _Position;
+			skipBlock();
+			if (_Position <= _Style.size())
+			{
+				ucstring rules;
+				rules.append(_Style, start + 1, _Position - start - 2);
+
+				parseRule(selector, rules);
+			}
+		}
+	}
+
+	// ***************************************************************************
+	// skip over \abcdef escaped sequence or escaped newline char
+	// @internal
+	void CCssParser::escape()
+	{
+		// skip '\'
+		_Position++;
+		if (is_hex(_Style[_Position]))
+		{
+			// TODO: '\abc def' should be considered one string
+			for(uint i=0; i<6 && is_hex(_Style[_Position]); i++)
+				_Position++;
+
+			if (_Style[_Position] == (ucchar)' ')
+				_Position++;
+		}
+		else if (_Style[_Position] != 0x0A)
+			_Position++;
+	}
+
+	// ***************************************************************************
+	// @internal
+	bool CCssParser::skipIdentifier()
+	{
+		size_t start = _Position;
+		bool valid = true;
+		while(!is_eof() && valid)
+		{
+			if (maybe_escape())
+			{
+				escape();
+				continue;
+			}
+			else if (is_alpha(_Style[_Position]))
+			{
+				// valid
+			}
+			else if (is_digit(_Style[_Position]))
+			{
+				if (_Position == start)
+				{
+					// cannot start with digit
+					valid = false;
+				}
+				else if ((_Position - start) == 0 && _Style[_Position-1] == (ucchar)'-')
+				{
+					// cannot start with -#
+					valid = false;
+				}
+			}
+			else if (_Style[_Position] == (ucchar)'_')
+			{
+				// valid
+			}
+			else if (_Style[_Position] >= 0x0080)
+			{
+				// valid
+			}
+			else if (_Style[_Position] == (ucchar)'-')
+			{
+				if ((_Position - start) == 1 && _Style[_Position-1] == (ucchar)'-')
+				{
+					// cannot start with --
+					valid = false;
+				}
+			}
+			else
+			{
+				// we're done
+				break;
+			}
+
+			_Position++;
+		}
+
+		return valid && !is_eof();
+	}
+
+	// ***************************************************************************
+	// skip over (..), [..], or {..} blocks
+	// @internal
+	void CCssParser::skipBlock()
+	{
+		ucchar startChar = _Style[_Position];
+
+		// block start
+		_Position++;
+		while(!is_eof() && !is_block_close(_Style[_Position], startChar))
+		{
+			if (maybe_escape())
+				// skip backslash and next char
+				_Position += 2;
+			else if (is_quote(_Style[_Position]))
+				skipString();
+			else if (is_block_open(_Style[_Position]))
+				skipBlock();
+			else
+				_Position++;
+		}
+
+		// block end
+		_Position++;
+	}
+
+	// ***************************************************************************
+	// skip over quoted string
+	// @internal
+	void CCssParser::skipString()
+	{
+		ucchar endChar = _Style[_Position];
+
+		// quote start
+		_Position++;
+		while(!is_eof() && _Style[_Position] != endChar)
+		{
+			if (maybe_escape())
+				_Position++;
+
+			_Position++;
+		}
+
+		// quote end
+		_Position++;
+	}
+
+	// ***************************************************************************
+	// @internal
+	void CCssParser::skipWhitespace()
+	{
+		while(!is_eof() && is_whitespace(_Style[_Position]))
+			_Position++;
+	}
+
+	// ***************************************************************************
+	// parse selector list
+	// @internal
+	std::vector<CCssSelector> CCssParser::parse_selector(const ucstring &sel, std::string &pseudoElement) const
+	{
+		std::vector<CCssSelector> result;
+		CCssSelector current;
+
+		pseudoElement.clear();
+
+		bool failed = false;
+		ucstring::size_type start = 0, pos = 0;
+		while(pos < sel.size())
+		{
+			ucstring uc;
+			uc = sel[pos];
+			if (is_nmchar(sel[pos]) && current.empty())
+			{
+				pos++;
+
+				while(pos < sel.size() && is_nmchar(sel[pos]))
+					pos++;
+
+				current.Element = toLower(sel.substr(start, pos - start).toUtf8());
+				start = pos;
+				continue;
+			}
+
+			if(sel[pos] == '#')
+			{
+				pos++;
+				start=pos;
+
+				while(pos < sel.size() && is_nmchar(sel[pos]))
+					pos++;
+
+				current.Id = toLower(sel.substr(start, pos - start).toUtf8());
+				start = pos;
+			}
+			else if (sel[pos] == '.')
+			{
+				pos++;
+				start=pos;
+
+				// .classA.classB
+				while(pos < sel.size() && (is_nmchar(sel[pos]) || sel[pos] == '.'))
+					pos++;
+
+				current.setClass(toLower(sel.substr(start, pos - start).toUtf8()));
+				start = pos;
+			}
+			else if (sel[pos] == '[')
+			{
+				pos++;
+				start = pos;
+
+				if (is_whitespace(sel[pos]))
+				{
+					while(pos < sel.size() && is_whitespace(sel[pos]))
+						pos++;
+
+					start = pos;
+				}
+
+				ucstring key;
+				ucstring value;
+				ucchar op = ' ';
+
+				// key
+				while(pos < sel.size() && is_nmchar(sel[pos]))
+					pos++;
+
+				key = sel.substr(start, pos - start);
+				if (pos == sel.size()) break;
+
+				if (is_whitespace(sel[pos]))
+				{
+					while(pos < sel.size() && is_whitespace(sel[pos]))
+						pos++;
+
+					if (pos == sel.size()) break;
+				}
+
+				if (sel[pos] == ']')
+				{
+					current.addAttribute(key.toUtf8());
+				}
+				else
+				{
+					// operand
+					op = sel[pos];
+					if (op == '~' || op == '|' || op == '^' || op == '$' || op == '*')
+					{
+						pos++;
+						if (pos == sel.size()) break;
+					}
+
+					// invalid rule?, eg [attr^value]
+					if (sel[pos] != '=')
+					{
+						while(pos < sel.size() && sel[pos] != ']')
+							pos++;
+
+						if (pos == sel.size()) break;
+
+						start = pos;
+					}
+					else
+					{
+						// skip '='
+						pos++;
+
+						if (is_whitespace(sel[pos]))
+						{
+							while(pos < sel.size() && is_whitespace(sel[pos]))
+								pos++;
+
+							if (pos == sel.size()) break;
+						}
+
+						// value
+						start = pos;
+						bool quote = false;
+						char quoteOpen;
+						while(pos < sel.size())
+						{
+							if (sel[pos] == '\'' || sel[pos] == '"')
+							{
+								// value is quoted
+								start = pos;
+								pos++;
+								while(pos < sel.size() && sel[pos] != sel[start])
+								{
+									if (sel[pos] == '\\')
+									{
+										pos++;
+									}
+									pos++;
+								}
+
+								if (pos == sel.size()) break;
+
+								value = sel.substr(start + 1, pos - start - 1);
+								break;
+							}
+							else if (sel[pos] == '\\')
+							{
+								pos++;
+							}
+							else if (!quote && sel[pos] == ']')
+							{
+								// unquoted value
+								value = sel.substr(start, pos - start);
+								break;
+							}
+
+							pos++;
+						} // while 'value'
+
+						// TODO: scan for sel[pos] == ']'
+						if (pos == sel.size()) break;
+						// whitespace between quote and ], ie '[ attr $= "val" ]'
+						if (sel[pos] != ']')
+						{
+							while(pos < sel.size() && sel[pos] != ']')
+								pos++;
+						}
+						if (pos == sel.size()) break;
+
+						current.addAttribute(key.toUtf8(), value.toUtf8(), (char)op);
+					} // op error
+				} // no value
+
+				// skip ']'
+				pos++;
+
+				start = pos;
+			}
+			else if (sel[pos] == ':')
+			{
+				pos++;
+				start=pos;
+				// pseudo element, eg '::before'
+				if (pos < sel.size() && sel[pos] == ':')
+				{
+					pos++;
+				}
+				// :first-child
+				// :nth-child(2n+0)
+				// :not(h1, div#main)
+				// :not(:nth-child(2n+0))
+				// has no support for quotes, eg  :not(h1[attr=")"]) fails
+				while(pos < sel.size() && (is_nmchar(sel[pos]) || sel[pos] == '('))
+				{
+					if (sel[pos] == '(')
+					{
+						uint open = 1;
+						pos++;
+						while(pos < sel.size() && open > 0)
+						{
+							if (sel[pos] == ')')
+								open--;
+							else if (sel[pos] == '(')
+								open++;
+
+							pos++;
+						}
+						break;
+					}
+					else
+					{
+						pos++;
+					}
+				}
+
+				std::string key = toLower(sel.substr(start, pos - start).toUtf8());
+				if (key.empty())
+				{
+					failed = true;
+					break;
+				}
+
+				if (key[0] == ':' || key == "after" || key == "before" || key == "cue" || key == "first-letter" || key == "first-line")
+				{
+					if (!pseudoElement.empty())
+					{
+						failed = true;
+						break;
+					}
+					if (key[0] != ':')
+					{
+						pseudoElement = ":" + key;
+					}
+					else
+					{
+						pseudoElement = key;
+					}
+				}
+				else
+				{
+					current.addPseudoClass(key);
+				}
+
+				start = pos;
+			}
+			else if (!current.empty())
+			{
+				// pseudo element like ':before' can only be set on the last selector
+				// user action pseudo classes can be used after pseudo element (ie, :focus, :hover)
+				// there is no support for those and its safe to just fail the selector
+				if (!result.empty() && !pseudoElement.empty())
+				{
+					failed = true;
+					break;
+				}
+
+				// start new selector as combinator is part of next selector
+				result.push_back(current);
+				current = CCssSelector();
+
+				// detect and remove whitespace around combinator, eg ' > '
+				bool isSpace = is_whitespace(sel[pos]);;
+				while(pos < sel.size() && is_whitespace(sel[pos]))
+					pos++;
+
+				if (sel[pos] == '>' || sel[pos] == '+' || sel[pos] == '~')
+				{
+					current.Combinator = sel[pos];
+					pos++;
+
+					while(pos < sel.size() && is_whitespace(sel[pos]))
+						pos++;
+				}
+				else if (isSpace)
+				{
+					current.Combinator = ' ';
+				}
+				else
+				{
+					// unknown
+					current.Combinator = sel[pos];
+					pos++;
+				}
+
+				start = pos;
+			}
+			else
+			{
+				pos++;
+			}
+		}
+
+		if (failed)
+		{
+			result.clear();
+		}
+		else if (result.empty() || !current.empty())
+		{
+			// pseudo element like ':before' can only be set on the last selector
+			if (!result.empty() && !pseudoElement.empty())
+			{
+				// failed
+				result.clear();
+			}
+			else
+			{
+				result.push_back(current);
+			}
+		}
+
+		return result;
+	}
+
+	// ***************************************************************************
+	// @internal
+	void CCssParser::preprocess()
+	{
+		_Position = 0;
+
+		size_t start;
+		size_t charsLeft;
+		bool quote = false;
+		ucchar quoteChar;
+		while(!is_eof())
+		{
+			charsLeft = _Style.size() - _Position - 1;
+
+			// FF, CR
+			if (_Style[_Position] == 0x0C || _Style[_Position] == 0x0D)
+			{
+				uint len = 1;
+				// CR, LF
+				if (charsLeft >= 1 && _Style[_Position] == 0x0D && _Style[_Position+1] == 0x0A)
+					len++;
+
+				ucstring tmp;
+				tmp += 0x000A;
+				_Style.replace(_Position, 1, tmp);
+			}
+			else if (_Style[_Position] == 0x00)
+			{
+				// Unicode replacement character
+				_Style[_Position] = 0xFFFD;
+			}
+			else
+			{
+				// strip comments for easier parsing
+				if (_Style[_Position] == '\\')
+				{
+					_Position++;
+				}
+				else if (is_quote(_Style[_Position]))
+				{
+					if (!quote)
+						quoteChar = _Style[_Position];
+
+					if (quote && _Style[_Position] == quoteChar)
+						quote = !quote;
+				}
+				else if (!quote && is_comment_open())
+				{
+					size_t pos = _Style.find(ucstring("*/"), _Position + 2);
+					if (pos == std::string::npos)
+						pos = _Style.size();
+
+					_Style.erase(_Position, pos - _Position + 2);
+					ucstring uc;
+					uc = _Style[_Position];
+
+					// _Position is already at correct place
+					continue;
+				}
+			}
+
+			_Position++;
+		}
+	}
 } // namespace
 
diff --git a/code/nel/src/gui/css_selector.cpp b/code/nel/src/gui/css_selector.cpp
new file mode 100644
index 000000000..0384f561a
--- /dev/null
+++ b/code/nel/src/gui/css_selector.cpp
@@ -0,0 +1,314 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "stdpch.h"
+
+#include <string>
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_selector.h"
+#include "nel/gui/html_element.h"
+
+using namespace NLMISC;
+
+#ifdef DEBUG_NEW
+#define new DEBUG_NEW
+#endif
+
+namespace NLGUI
+{
+	CCssSelector::CCssSelector(std::string elm, std::string id, std::string cls, char comb)
+		: Element(elm), Id(id), Class(), Attr(), PseudoClass(), Combinator(comb)
+	{
+		if (!cls.empty())
+		{
+			setClass(cls);
+		}
+	}
+
+	uint32 CCssSelector::specificity() const
+	{
+		uint ret = 0;
+
+		if (!Element.empty() && Element != "*") ret += 0x000001;
+		// Pseudo Element is added in CCssStyle
+		//if (!PseudoElement.empty())             ret += 0x000001;
+
+		if (!Class.empty())                     ret += 0x000100 * Class.size();
+		if (!Attr.empty())                      ret += 0x000100 * Attr.size();
+		// TODO: has different cases
+		if (!PseudoClass.empty())               ret += 0x000100 * PseudoClass.size();
+
+		if (!Id.empty())                        ret += 0x010000;
+
+		return ret;
+	}
+
+	void CCssSelector::setClass(const std::string &cls)
+	{
+		std::vector<std::string> parts;
+		NLMISC::splitString(toLower(cls), ".", parts);
+
+		for(uint i = 0; i< parts.size(); i++)
+		{
+			std::string cname = trim(parts[i]);
+			if (!cname.empty())
+			{
+				Class.push_back(cname);
+			}
+		}
+	}
+
+	void CCssSelector::addAttribute(const std::string &key, const std::string &val, char op)
+	{
+		Attr.push_back(SAttribute(key, val, op));
+	}
+
+	void CCssSelector::addPseudoClass(const std::string &key)
+	{
+		if (key.empty()) return;
+
+		PseudoClass.push_back(key);
+	}
+
+	bool CCssSelector::match(const CHtmlElement &elm) const
+	{
+		if (!Element.empty() && Element != "*" && Element != elm.Value)
+		{
+			return false;
+		}
+
+		if (!Id.empty() && Id != elm.getAttribute("id"))
+		{
+			return false;
+		}
+
+		if (!Class.empty() && !matchClass(elm))
+		{
+			return false;
+		}
+
+		if (!Attr.empty() && !matchAttributes(elm))
+		{
+			return false;
+		}
+
+		if (!PseudoClass.empty() && !matchPseudoClass(elm))
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	bool CCssSelector::matchClass(const CHtmlElement &elm) const
+	{
+		// make sure all class names we have, other has as well
+		for(uint i = 0; i< Class.size(); ++i)
+		{
+			if (!elm.hasClass(Class[i]))
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	bool CCssSelector::matchAttributes(const CHtmlElement &elm) const
+	{
+		// TODO: refactor into matchAttributeSelector
+		for(uint i = 0; i< Attr.size(); ++i)
+		{
+			if (!elm.hasAttribute(Attr[i].key)) return false;
+
+			std::string value = elm.getAttribute(Attr[i].key);
+			switch(Attr[i].op)
+			{
+				case '=':
+					if (Attr[i].value != value) return false;
+					break;
+				case '~':
+					{
+						// exact match to any of whitespace separated words from element attribute
+						if (Attr[i].value.empty()) return false;
+
+						std::vector<std::string> parts;
+						NLMISC::splitString(value, " ", parts);
+						bool found = false;
+						for(uint j = 0; j < parts.size(); j++)
+						{
+							if (Attr[i].value == parts[j])
+							{
+								found = true;
+								break;
+							}
+						}
+						if (!found) return false;
+					}
+					break;
+				case '|':
+					// exact value, or start with val+'-'
+					if (value != Attr[i].value && value.find(Attr[i].value + "-") == std::string::npos) return false;
+					break;
+				case '^':
+					// prefix, starts with
+					if (Attr[i].value.empty()) return false;
+					if (value.find(Attr[i].value) != 0) return false;
+					break;
+				case '$':
+					// suffic, ends with
+					if (Attr[i].value.empty() || value.size() < Attr[i].value.size()) return false;
+					if (Attr[i].value == value.substr(value.size() - Attr[i].value.size())) return false;
+					break;
+				case '*':
+					if (Attr[i].value.empty()) return false;
+					if (value.find(Attr[i].value) == std::string::npos) return false;
+					break;
+				case ' ':
+					// contains key, ignore value
+					break;
+				default:
+					// unknown comparison
+					return false;
+			}
+		}
+
+		return true;
+	}
+
+	bool CCssSelector::matchPseudoClass(const CHtmlElement &elm) const
+	{
+		for(uint i = 0; i< PseudoClass.size(); i++)
+		{
+			if (PseudoClass[i] == "root")
+			{
+				// ':root' is just 'html' with higher specificity
+				if (elm.Value != "html") return false;
+			}
+			else if (PseudoClass[i] == "only-child")
+			{
+				if (elm.parent && !elm.parent->Children.empty()) return false;
+			}
+			else
+			{
+				if (PseudoClass[i] == "first-child")
+				{
+					if (elm.previousSibling) return false;
+				}
+				else if (PseudoClass[i] == "last-child")
+				{
+					if (elm.nextSibling) return false;
+				}
+				else if (PseudoClass[i].find("nth-child(") != std::string::npos)
+				{
+					sint a, b;
+					// TODO: there might be multiple :nth-child() on single selector, so current can't cache it
+					parseNth(PseudoClass[i], a, b);
+
+					// 1st child should be '1' and not '0'
+					if (!matchNth(elm.childIndex+1, a, b)) return false;
+				}
+				else
+				{
+					return false;
+				}
+			}
+		}
+
+		return true;
+	}
+
+	void CCssSelector::parseNth(const std::string &pseudo, sint &a, sint &b) const
+	{
+		a = 0;
+		b = 0;
+
+		std::string::size_type start = pseudo.find_first_of("(") + 1;
+		std::string::size_type end = pseudo.find_first_of(")");
+
+		if (start == std::string::npos) return;
+
+		std::string expr = toLower(pseudo.substr(start, end - start));
+
+		if (expr.empty()) return;
+
+		if (expr == "even")
+		{
+			// 2n+0
+			a = 2;
+			b = 0;
+		}
+		else if (expr == "odd")
+		{
+			// 2n+1
+			a = 2;
+			b = 1;
+		}
+		else
+		{
+			// -An+B, An+B, An-B
+			std::string::size_type pos;
+
+			start = 0;
+			pos = expr.find_first_of("n", start);
+			if (pos == std::string::npos)
+			{
+				fromString(expr, b);
+			}
+			else if (pos == 0)
+			{
+				// 'n' == '1n'
+				a = 1;
+			}
+			else if (expr[0] == '-' && pos == 1)
+			{
+				// '-n' == '-1n'
+				a = -1;
+			}
+			else
+			{
+				fromString(expr.substr(start, pos - start), a);
+			}
+
+			start = pos;
+			pos = expr.find_first_of("+-", start);
+			if (pos != std::string::npos && (expr[pos] == '+' || expr[pos] == '-'))
+			{
+				// copy with sign char
+				fromString(expr.substr(pos, end - pos), b);
+			}
+		}
+	}
+
+	bool CCssSelector::matchNth(sint childNr, sint a, sint b) const
+	{
+		if (a == 0)
+		{
+			return childNr == b;
+		}
+		else if (a > 0)
+		{
+			return childNr >= b && (childNr - b) % a == 0;
+		}
+		else
+		{
+			// a is negative from '-An+B'
+			return childNr <= b && (b - childNr) % (-a) == 0;
+		}
+	}
+
+} // namespace
+
diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp
index 8fc1207d2..88e438870 100644
--- a/code/nel/src/gui/css_style.cpp
+++ b/code/nel/src/gui/css_style.cpp
@@ -18,6 +18,7 @@
 
 #include <string>
 #include "nel/misc/types_nl.h"
+#include "nel/gui/html_element.h"
 #include "nel/gui/css_style.h"
 #include "nel/gui/css_parser.h"
 #include "nel/gui/libwww.h"
@@ -30,24 +31,236 @@ using namespace NLMISC;
 
 namespace NLGUI
 {
+	uint CCssStyle::SStyleRule::specificity() const
+	{
+		uint count = 0;
+		for(uint i = 0; i < Selector.size(); ++i)
+		{
+			count += Selector[i].specificity();
+		}
+		// counted as element tag like DIV
+		if (!PseudoElement.empty())
+		{
+			count += 0x000001;
+		}
+
+		return count;
+	}
+
 	// ***************************************************************************
 	void CCssStyle::reset()
 	{
+		_StyleRules.clear();
 		_StyleStack.clear();
 
 		Root = CStyleParams();
 		Current = CStyleParams();
 	}
 
+	// ***************************************************************************
+	// Sorting helper
+	struct CCssSpecificityPred
+	{
+		bool operator()(CCssStyle::SStyleRule lhs, CCssStyle::SStyleRule rhs) const
+		{
+			return lhs.specificity() < rhs.specificity();
+		}
+	};
+
+	// ***************************************************************************
+	void CCssStyle::parseStylesheet(const std::string &styleString)
+	{
+		CCssParser parser;
+		parser.parseStylesheet(styleString, _StyleRules);
+
+		// keep the list sorted
+		std::stable_sort(_StyleRules.begin(), _StyleRules.end(), CCssSpecificityPred());
+	}
+
+	void CCssStyle::getStyleFor(CHtmlElement &elm) const
+	{
+		std::vector<SStyleRule> mRules;
+		for (std::vector<SStyleRule>::const_iterator it = _StyleRules.begin(); it != _StyleRules.end(); ++it)
+		{
+			if (match(it->Selector, elm))
+			{
+				mRules.push_back(*it);
+			}
+		}
+
+		elm.Style.clear();
+		elm.StyleBefore.clear();
+		elm.StyleAfter.clear();
+
+		if (!mRules.empty())
+		{
+			// style is sorted by specificity (lowest first), eg. html, .class, html.class, #id, html#id.class
+			for(std::vector<SStyleRule>::const_iterator i = mRules.begin(); i != mRules.end(); ++i)
+			{
+				if (i->PseudoElement.empty())
+				{
+					merge(elm.Style, i->Properties);
+				}
+				else if (i->PseudoElement == ":before")
+				{
+					merge(elm.StyleBefore, i->Properties);
+				}
+				else if (i->PseudoElement == ":after")
+				{
+					merge(elm.StyleAfter, i->Properties);
+				}
+			}
+		}
+
+		// style from "style" attribute overrides <style>
+		if (elm.hasNonEmptyAttribute("style"))
+		{
+			TStyle styles = CCssParser::parseDecls(elm.getAttribute("style"));
+			merge(elm.Style, styles);
+		}
+	}
+
+	void CCssStyle::merge(TStyle &dst, const TStyle &src) const
+	{
+		// TODO: does not use '!important' flag
+		for(TStyle::const_iterator it = src.begin(); it != src.end(); ++it)
+		{
+			dst[it->first] = it->second;
+		}
+	}
+
+	bool CCssStyle::match(const std::vector<CCssSelector> &selector, const CHtmlElement &elm) const
+	{
+		if (selector.empty()) return false;
+
+		// first selector, '>' immediate parent
+		bool matches = false;
+		bool mustMatchNext = true;
+		bool matchGeneralChild = false;
+		bool matchGeneralSibling = false;
+
+		const CHtmlElement *child;
+		child = &elm;
+		std::vector<CCssSelector>::const_reverse_iterator ritSelector = selector.rbegin();
+		char matchCombinator = '\0';
+		while(ritSelector != selector.rend())
+		{
+			if (!child)
+			{
+				return false;
+			}
+
+			matches = ritSelector->match(*child);
+			if (!matches && mustMatchNext)
+			{
+				return false;
+			}
+
+			if (!matches)
+			{
+				if (matchCombinator == ' ')
+				{
+					if (!child->parent)
+					{
+						return false;
+					}
+					child = child->parent;
+					// walk up the tree until there is match for current selector
+					continue;
+				}
+
+				if (matchCombinator == '~')
+				{
+					// any previous sibling must match current selector
+					if (!child->previousSibling)
+					{
+						return false;
+					}
+					child = child->previousSibling;
+
+					// check siblings until there is match for current selector
+					continue;
+				}
+			}
+
+			mustMatchNext = false;
+			switch(ritSelector->Combinator)
+			{
+			case '\0':
+				// default case when single selector
+				break;
+			case ' ':
+				{
+					// general child - match child->parent to current/previous selector
+					if (!child->parent)
+					{
+						return false;
+					}
+					child = child->parent;
+					matchCombinator = ritSelector->Combinator;
+				}
+				break;
+			case '~':
+				{
+					// any previous sibling must match current selector
+					if (!child->previousSibling)
+					{
+						return false;
+					}
+					child = child->previousSibling;
+					matchCombinator = ritSelector->Combinator;
+				}
+				break;
+			case '+':
+				{
+					// adjacent sibling - previous sibling must match previous selector
+					if (!child->previousSibling)
+					{
+						return false;
+					}
+					child = child->previousSibling;
+					mustMatchNext = true;
+				}
+				break;
+			case '>':
+				{
+					// child of - immediate parent must match previous selector
+					if (!child->parent)
+					{
+						return false;					
+					}
+					child = child->parent;
+					mustMatchNext = true;
+				}
+				break;
+			default:
+				// should not reach
+				return false;
+			}
+
+			++ritSelector;
+		}
+
+		return matches;
+	}
+
 	// ***************************************************************************
 	void CCssStyle::applyRootStyle(const std::string &styleString)
 	{
 		getStyleParams(styleString, Root, Root);
 	}
 
+	// ***************************************************************************
+	void CCssStyle::applyRootStyle(const TStyle &styleRules)
+	{
+		getStyleParams(styleRules, Root, Root);
+	}
+
 	// ***************************************************************************
 	void CCssStyle::applyStyle(const std::string &styleString)
 	{
+		if (styleString.empty()) return;
+
 		if (_StyleStack.empty())
 		{
 			getStyleParams(styleString, Current, Root);
@@ -58,6 +271,20 @@ namespace NLGUI
 		}
 	}
 
+	// ***************************************************************************
+	void CCssStyle::applyStyle(const TStyle &styleRules)
+	{
+		if (_StyleStack.empty())
+		{
+			getStyleParams(styleRules, Current, Root);
+		}
+		else
+		{
+			getStyleParams(styleRules, Current, _StyleStack.back());
+		}
+	}
+
+	// ***************************************************************************
 	bool CCssStyle::scanCssLength(const std::string& str, uint32 &px) const
 	{
 		if (fromString(str, px))
@@ -90,14 +317,30 @@ namespace NLGUI
 	// style.StrikeThrough; // text-decoration: line-through;  text-decoration-line: line-through;
 	void CCssStyle::getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current) const
 	{
-		float tmpf;
 		TStyle styles = CCssParser::parseDecls(styleString);
-		TStyle::iterator it;
 
-		// first pass: get font-size for 'em' sizes
-		// get TextColor value used as 'currentcolor'
-		for (it=styles.begin(); it != styles.end(); ++it)
+		getStyleParams(styles, style, current);
+	}
+
+	void CCssStyle::getStyleParams(const TStyle &styleRules, CStyleParams &style, const CStyleParams &current) const
+	{
+		float tmpf;
+		TStyle::const_iterator it;
+
+		if(styleRules.empty())
 		{
+			return;
+		}
+
+		// first pass:
+		// - get font-size for 'em' sizes
+		// - split shorthand to its parts
+		// - get TextColor value that could be used for 'currentcolor'
+		for (it=styleRules.begin(); it != styleRules.end(); ++it)
+		{
+			// update local copy of applied style
+			style.StyleRules[it->first] = it->second;
+
 			if (it->first == "color")
 			{
 				if (it->second == "inherit")
@@ -180,19 +423,56 @@ namespace NLGUI
 					}
 				}
 			}
+			else
+			if (it->first == "background")
+			{
+				parseBackgroundShorthand(it->second, style);
+			}
 		}
 
 		// second pass: rest of style
-		for (it=styles.begin(); it != styles.end(); ++it)
+		for (it=styleRules.begin(); it != styleRules.end(); ++it)
 		{
-			if (it->first == "border")
+			if (it->first == "border" || it->first == "border-width")
 			{
-				sint32 b;
-				if (it->second == "none")
+				// TODO: border: 1px solid red;
+				if (it->second == "inherit")
+				{
+					style.BorderWidth = current.BorderWidth;
+				}
+				else if (it->second == "none")
+				{
 					style.BorderWidth = 0;
-				else
-				if (fromString(it->second, b))
-					style.BorderWidth = b;
+				}
+				else if (it->second == "thin")
+				{
+					style.BorderWidth = 1;
+				}
+				else if (it->second == "medium")
+				{
+					style.BorderWidth = 3;
+				}
+				else if (it->second == "thick")
+				{
+					style.BorderWidth = 5;
+				}
+				else 
+				{
+					std::string unit;
+					if (getCssLength(tmpf, unit, it->second.c_str()))
+					{
+						if (unit == "rem")
+							style.BorderWidth = Root.FontSize * tmpf;
+						else if (unit == "em")
+							style.BorderWidth = current.FontSize * tmpf;
+						else if (unit == "pt")
+							style.BorderWidth = tmpf / 0.75f;
+						else if (unit == "%")
+							style.BorderWidth = 0; // no support for % in border width
+						else
+							style.BorderWidth = tmpf;
+					}
+				}
 			}
 			else
 			if (it->first == "font-style")
@@ -366,6 +646,30 @@ namespace NLGUI
 				}
 			}
 			else
+			if (it->first == "text-align")
+			{
+				if (it->second == "inherit")
+					style.TextAlign = current.TextAlign;
+				else if (it->second == "left" || it->second == "right" || it->second == "center" || it->second == "justify")
+					style.TextAlign = it->second;
+			}
+			else
+			if (it->first == "vertical-align")
+			{
+				if (it->second == "inherit")
+					style.VerticalAlign = current.VerticalAlign;
+				else if (it->second == "top" || it->second == "middle" || it->second == "bottom")
+					style.VerticalAlign = it->second;
+			}
+			else
+			if (it->first == "white-space")
+			{
+				if (it->second == "inherit")
+					style.WhiteSpace = current.WhiteSpace;
+				else if (it->second == "normal" || it->second == "nowrap" || it->second == "pre")
+					style.WhiteSpace = it->second;
+			}
+			else
 			if (it->first == "width")
 			{
 				std::string unit;
@@ -474,6 +778,172 @@ namespace NLGUI
 			style.StrikeThrough = current.StrikeThrough;
 	}
 
+	void CCssStyle::parseBackgroundShorthand(const std::string &value, CStyleParams &style) const
+	{
+		// background: url(image.jpg) top center / 200px 200px no-repeat fixed padding-box content-box red;
+		// background-image      : url(image.jpg)
+		// background-position   : top center
+		// background-size       : 200px 200px
+		// background-repeat     : no-repeat
+		// background-attachment : fixed
+		// background-origin     : padding-box
+		// background-clip       : content-box
+		// background-color      : red
+
+		const uint nbProps = 8;
+		std::string props[nbProps] = {"background-image", "background-position", "background-size", "background-repeat",
+			"background-attachment", "background-origin", "background-clip", "background-color"};
+		std::string values[nbProps];
+		bool found[nbProps] = {false};
+
+
+		uint partIndex = 0;
+		std::vector<std::string> parts;
+		std::vector<std::string>::iterator it;
+		// FIXME: this will fail if url() contains ' ' chars
+		NLMISC::splitString(value, " ", parts);
+
+		bool failed = false;
+		for(uint index = 0; index < parts.size(); index++)
+		{
+			const std::string val = toLower(trim(parts[index]));
+
+			for(uint i = 0; i < nbProps; i++)
+			{
+				if (found[i])
+				{
+					continue;
+				}
+
+				if (props[i] == "background-image")
+				{
+					if (val.substr(0, 4) == "url(")
+					{
+						// use original value as 'val' is lowercase
+						values[i] = parts[index];
+						found[i] = true;
+					}
+				}
+				else if (props[i] == "background-position")
+				{
+					// TODO:
+				}
+				else if (props[i] == "background-size")
+				{
+					// TODO: [<length-percentage> | auto ]{1,2} cover | contain
+				}
+				else if (props[i] == "background-repeat")
+				{
+					if (val == "repeat-x" || val == "repeat-y" || val == "repeat" || val == "space" || val == "round" || val == "no-repeat")
+					{
+						if (val == "repeat-x")
+						{
+							values[i] = "repeat no-repeat";
+						}
+						else if (val == "repeat-y")
+						{
+							values[i] = "no-repeat repeat";				
+						}
+						else
+						{
+							std::string horiz = val;
+							std::string vert = val;
+							if (index+1 < parts.size())
+							{
+								std::string next = toLower(trim(parts[index+1]));
+								if (next == "repeat" || next == "space" || next == "round" || next == "no-repeat")
+								{
+									vert = next;
+									index++;
+								}
+							}
+							
+							values[i] = horiz + " " + vert;
+						}
+
+						found[i] = true;
+					}
+				}
+				else if (props[i] == "background-attachment")
+				{
+					// TODO: scroll | fixed | local
+				}
+				else if (props[i] == "background-origin" || props[i] == "background-clip")
+				{
+					// same values for both
+					if (val == "padding-box" || val == "border-box" || val == "content-box")
+					{
+						values[i] = val;
+						found[i] = true;
+					}
+				}
+				else if (props[i] == "background-color")
+				{
+					CRGBA color;
+					if (!scanHTMLColor(val.c_str(), color))
+					{
+						failed = true;
+						break;
+					}
+					values[i] = val;
+					// color should come as last item
+					break;
+				}
+			}
+		}
+
+		// invalidate whole rule
+		if (failed)
+		{
+			return;
+		}
+
+		// apply found styles
+		for(uint i = 0; i < nbProps; i++)
+		{
+			if (found[i])
+			{
+				style.StyleRules[props[i]] = values[i];
+			}
+			else
+			{
+				// fill in default if one is set
+				if (props[i] == "background-image")
+				{
+					style.StyleRules[props[i]] = "none";
+				}
+				else if (props[i] == "background-position")
+				{
+					//style.StyleRules[props[i]] = "0% 0%";
+				}
+				else if (props[i] == "background-size")
+				{
+					//style.StyleRules[props[i]] = "auto auto";
+				}
+				else if (props[i] == "background-repeat")
+				{
+					style.StyleRules[props[i]] = "repeat repeat";
+				}
+				else if(props[i] == "background-attachment")
+				{
+					//style.StyleRules[props[i]] = "scroll";
+				}
+				else if(props[i] == "background-origin")
+				{
+					//style.StyleRules[props[i]] = "padding-box";
+				}
+				else if (props[i] == "background-clip")
+				{
+					//style.StyleRules[props[i]] = "border-box";
+				}
+				else if (props[i] == "background-color")
+				{
+					style.StyleRules[props[i]] = "transparent";
+				}
+			}
+		}
+	}
+
 	// ***************************************************************************
 	void CCssStyle::applyCssMinMax(sint32 &width, sint32 &height, sint32 minw, sint32 minh, sint32 maxw, sint32 maxh) const
 	{
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index ba21c6af1..c40617f50 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -49,6 +49,9 @@
 #include "nel/gui/http_hsts.h"
 #include "nel/gui/curl_certificates.h"
 #include "nel/gui/html_parser.h"
+#include "nel/gui/html_element.h"
+#include "nel/gui/css_style.h"
+#include "nel/gui/css_parser.h"
 
 #include <curl/curl.h>
 
@@ -69,7 +72,6 @@ using namespace NLMISC;
 
 namespace NLGUI
 {
-
 	// Uncomment to see the log about image download
 	//#define LOG_DL 1
 
@@ -395,22 +397,22 @@ namespace NLGUI
 			setTextStyle(pVT, style);
 		}
 
-		if (style.BackgroundColor.A > 0)
+		if (style.hasStyle("background-color"))
 		{
 			ctrlButton->setColor(style.BackgroundColor);
-			if (style.BackgroundColorOver.A == 0)
+			if (style.hasStyle("-ryzom-background-color-over"))
 			{
-				ctrlButton->setColorOver(style.BackgroundColor);
+				ctrlButton->setColorOver(style.BackgroundColorOver);
 			}
 			else
 			{
-				ctrlButton->setColorOver(style.BackgroundColorOver);
+				ctrlButton->setColorOver(style.BackgroundColor);
 			}
 			ctrlButton->setTexture("", "blank.tga", "", false);
 			ctrlButton->setTextureOver("", "blank.tga", "");
 			ctrlButton->setProperty("force_text_over", "true");
 		}
-		else if (style.BackgroundColorOver.A > 0)
+		else if (style.hasStyle("-ryzom-background-color-over"))
 		{
 			ctrlButton->setColorOver(style.BackgroundColorOver);
 			ctrlButton->setProperty("force_text_over", "true");
@@ -424,7 +426,6 @@ namespace NLGUI
 		{
 			pVT->setFontSize(style.FontSize);
 			pVT->setColor(style.TextColor);
-			pVT->setColor(style.TextColor);
 			pVT->setFontName(style.FontFamily);
 			pVT->setFontSize(style.FontSize);
 			pVT->setEmbolden(style.FontWeight >= FONT_WEIGHT_BOLD);
@@ -450,6 +451,36 @@ namespace NLGUI
 		return dest;
 	}
 
+	void CGroupHTML::pumpCurlDownloads()
+	{
+		if (RunningCurls < options.curlMaxConnections)
+		{
+			for (vector<CDataDownload>::iterator it=Curls.begin(); it<Curls.end(); it++)
+			{
+				if (it->data == NULL)
+				{
+					#ifdef LOG_DL
+					nlwarning("(%s) starting new download '%s'", _Id.c_str(), it->url.c_str());
+					#endif
+					if (!startCurlDownload(*it))
+					{
+						finishCurlDownload(*it);
+						Curls.erase(it);
+						break;
+					}
+
+					RunningCurls++;
+					if (RunningCurls >= options.curlMaxConnections)
+						break;
+				}
+			}
+		}
+		#ifdef LOG_DL
+		if (RunningCurls > 0 || !Curls.empty())
+			nlwarning("(%s) RunningCurls %d, _Curls %d", _Id.c_str(), RunningCurls, Curls.size());
+		#endif
+	}
+
 	// Add url to MultiCurl queue and return cURL handle
 	bool CGroupHTML::startCurlDownload(CDataDownload &download)
 	{
@@ -543,6 +574,86 @@ namespace NLGUI
 		return true;
 	}
 
+	void CGroupHTML::finishCurlDownload(CDataDownload &download)
+	{
+		std::string tmpfile = download.dest + ".tmp";
+
+		if (download.type == ImgType)
+		{
+			// there is race condition if two browser instances are downloading same file
+			// second instance deletes first tmpfile and creates new file for itself.
+			if (CFile::getFileSize(tmpfile) > 0)
+			{
+				try
+				{
+					// verify that image is not corrupted
+					uint32 w, h;
+					CBitmap::loadSize(tmpfile, w, h);
+					if (w != 0 && h != 0)
+					{
+						bool refresh = false;
+						if (CFile::fileExists(download.dest))
+						{
+							CFile::deleteFile(download.dest);
+							refresh = true;
+						}
+
+						// to reload image on page, the easiest seems to be changing texture
+						// to temp file temporarily. that forces driver to reload texture from disk
+						// ITexture::touch() seem not to do this.
+						if (refresh)
+						{
+							// cache was updated, first set texture as temp file
+							for(uint i = 0; i < download.imgs.size(); i++)
+							{
+								setImage(download.imgs[i].Image, tmpfile, download.imgs[i].Type);
+								setImageSize(download.imgs[i].Image, download.imgs[i].Style);
+							}
+						}
+
+						// move temp to correct cache file
+						CFile::moveFile(download.dest, tmpfile);
+						// set image texture as cache file
+						for(uint i = 0; i < download.imgs.size(); i++)
+						{
+							setImage(download.imgs[i].Image, download.dest, download.imgs[i].Type);
+							setImageSize(download.imgs[i].Image, download.imgs[i].Style);
+						}
+
+					}
+				}
+				catch(const NLMISC::Exception &e)
+				{
+					// exception message has .tmp file name, so keep it for further analysis
+					nlwarning("Invalid image (%s): %s", download.url.c_str(), e.what());
+				}
+			}
+
+			return;
+		}
+
+		if (!tmpfile.empty())
+		{
+			CFile::moveFile(download.dest, tmpfile);
+		}
+
+		if (download.type == StylesheetType)
+		{
+			cssDownloadFinished(download.url, download.dest);
+
+			return;
+		}
+
+		if (download.type == BnpType)
+		{
+			CLuaManager::getInstance().executeLuaScript(download.luaScript, true );
+
+			return;
+		}
+
+		nlwarning("Unknown CURL download type (%d) finished '%s'", download.type, download.url.c_str());
+	}
+
 	// Add a image download request in the multi_curl
 	void CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style, TImageType type)
 	{
@@ -575,22 +686,8 @@ namespace NLGUI
 		}
 
 		Curls.push_back(CDataDownload(finalUrl, dest, ImgType, img, "", "", style, type));
-		if (Curls.size() < options.curlMaxConnections) {
-			if (!startCurlDownload(Curls.back()))
-			{
-				Curls.pop_back();
-				return;
-			}
 
-			RunningCurls++;
-	#ifdef LOG_DL
-			nlwarning("(%s) adding handle %x, %d curls", _Id.c_str(), Curls.back().data->Request, Curls.size());
-		}
-		else
-		{
-			nlwarning("(%s) download queued, %d curls", _Id.c_str(), Curls.size());
-	#endif
-		}
+		pumpCurlDownloads();
 	}
 
 	void CGroupHTML::initImageDownload()
@@ -651,22 +748,8 @@ namespace NLGUI
 		if (action != "delete")
 		{
 			Curls.push_back(CDataDownload(url, dest, BnpType, NULL, script, md5sum));
-			if (Curls.size() < options.curlMaxConnections)
-			{
-				if (!startCurlDownload(Curls.back()))
-				{
-					Curls.pop_back();
-					return false;
-				}
-				RunningCurls++;
-	#ifdef LOG_DL
-				nlwarning("(%s) adding handle %x, %d curls", _Id.c_str(), Curls.back().data->Request, Curls.size());
-			}
-			else
-			{
-				nlwarning("(%s) download queued, %d curls", _Id.c_str(), Curls.size());
-	#endif
-			}
+
+			pumpCurlDownloads();
 		}
 		else
 			return true;
@@ -687,6 +770,25 @@ namespace NLGUI
 			CFile::createDirectory( pathName );
 	}
 
+	void CGroupHTML::addStylesheetDownload(std::vector<std::string> links)
+	{
+		for(uint i = 0; i < links.size(); ++i)
+		{
+			std::string url = getAbsoluteUrl(links[i]);
+			std::string local = localImageName(url);
+
+			// insert only if url not already downloading
+			std::vector<std::string>::const_iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url);
+			if (it == _StylesheetQueue.end())
+			{
+				_StylesheetQueue.push_back(url);
+				Curls.push_back(CDataDownload(url, local, StylesheetType, NULL, "", ""));
+			}
+		}
+
+		pumpCurlDownloads();
+	}
+
 	// Call this evenly to check if an element is downloaded and then manage it
 	void CGroupHTML::checkDownloads()
 	{
@@ -826,7 +928,7 @@ namespace NLGUI
 								CStrictTransportSecurity::getInstance()->setFromHeader(uri.host, it->data->getHSTSHeader());
 							}
 
-							string tmpfile = it->dest + ".tmp";
+							std::string tmpfile = it->dest + ".tmp";
 							if(res != CURLE_OK || r < 200 || r >= 300 || (!it->md5sum.empty() && (it->md5sum != getMD5(tmpfile).toString())))
 							{
 								if (it->redirects < DEFAULT_RYZOM_REDIRECT_LIMIT && ((r >= 301 && r <= 303) || r == 307 || r == 308))
@@ -863,7 +965,7 @@ namespace NLGUI
 									if (it->redirects >= DEFAULT_RYZOM_REDIRECT_LIMIT)
 										nlwarning("Redirect limit reached for '%s'", it->url.c_str());
 
-									NLMISC::CFile::deleteFile(tmpfile.c_str());
+									CFile::deleteFile(tmpfile);
 
 									// 304 Not Modified
 									if (res == CURLE_OK && r == 304)
@@ -875,6 +977,14 @@ namespace NLGUI
 
 										CHttpCache::getInstance()->store(it->dest, obj);
 									}
+									else
+									{
+										// 404, 500, etc
+										if (CFile::fileExists(it->dest))
+											CFile::deleteFile(it->dest);
+									}
+
+									finishCurlDownload(*it);
 								}
 							}
 							else
@@ -886,46 +996,7 @@ namespace NLGUI
 
 								CHttpCache::getInstance()->store(it->dest, obj);
 
-								string finalUrl;
-								if (it->type == ImgType)
-								{
-									// there is race condition if two browser instances are downloading same file
-									// second instance deletes first tmpfile and creates new file for itself.
-									if (CFile::getFileSize(tmpfile) > 0)
-									{
-										try
-										{
-											// verify that image is not corrupted
-											uint32 w, h;
-											CBitmap::loadSize(tmpfile, w, h);
-											if (w != 0 && h != 0)
-											{
-												if (CFile::fileExists(it->dest))
-													CFile::deleteFile(it->dest);
-
-												CFile::moveFile(it->dest, tmpfile);
-												for(uint i = 0; i < it->imgs.size(); i++)
-												{
-													setImage(it->imgs[i].Image, it->dest, it->imgs[i].Type);
-													setImageSize(it->imgs[i].Image, it->imgs[i].Style);
-												}
-											}
-										}
-										catch(const NLMISC::Exception &e)
-										{
-											// exception message has .tmp file name, so keep it for further analysis
-											nlwarning("Invalid image (%s): %s", it->url.c_str(), e.what());
-										}
-									}
-								}
-								else
-								{
-									CFile::moveFile(it->dest, tmpfile);
-									//if (lookupLocalFile (finalUrl, file.c_str(), false))
-									{
-										CLuaManager::getInstance().executeLuaScript( it->luaScript, true );
-									}
-								}
+								finishCurlDownload(*it);
 							}
 
 							// release CCurlWWWData
@@ -941,31 +1012,7 @@ namespace NLGUI
 
 		RunningCurls = NewRunningCurls;
 
-		if (RunningCurls < options.curlMaxConnections)
-		{
-			for (vector<CDataDownload>::iterator it=Curls.begin(); it<Curls.end(); it++)
-			{
-				if (it->data == NULL) {
-	#ifdef LOG_DL
-					nlwarning("(%s) starting new download '%s'", _Id.c_str(), it->url.c_str());
-	#endif
-					if (!startCurlDownload(*it))
-					{
-						Curls.erase(it);
-						break;
-					}
-
-					RunningCurls++;
-					if (RunningCurls >= options.curlMaxConnections)
-						break;
-				}
-			}
-		}
-
-	#ifdef LOG_DL
-		if (RunningCurls > 0 || !Curls.empty())
-			nlwarning("(%s) RunningCurls %d, _Curls %d", _Id.c_str(), RunningCurls, Curls.size());
-	#endif
+		pumpCurlDownloads();
 	}
 
 
@@ -1117,7 +1164,7 @@ namespace NLGUI
 
 	// ***************************************************************************
 
-	#define getCellsParameters(prefix,inherit) \
+	#define getCellsParameters_DEP(prefix,inherit) \
 	{\
 		CGroupHTML::CCellParams cellParams; \
 		if (!_CellParams.empty() && inherit) \
@@ -1154,8 +1201,310 @@ namespace NLGUI
 	}
 
 	// ***************************************************************************
+	void CGroupHTML::beginElement (CHtmlElement &elm)
+	{
+		_Style.pushStyle();
+		_CurrentHTMLElement = &elm;
+		_CurrentHTMLNextSibling = elm.nextSibling;
 
-	void CGroupHTML::beginElement (uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value)
+		// set element style from css and style attribute
+		_Style.getStyleFor(elm);
+		if (!elm.Style.empty())
+		{
+			_Style.applyStyle(elm.Style);
+		}
+
+		if (elm.hasNonEmptyAttribute("name"))
+		{
+			_AnchorName.push_back(elm.getAttribute("name"));
+		}
+		if (elm.hasNonEmptyAttribute("id"))
+		{
+			_AnchorName.push_back(elm.getAttribute("id"));
+		}
+
+		switch(elm.ID)
+		{
+		case HTML_A:        htmlA(elm); break;
+		case HTML_BASE:     htmlBASE(elm); break;
+		case HTML_BODY:     htmlBODY(elm); break;
+		case HTML_BR:       htmlBR(elm); break;
+		case HTML_DD:       htmlDD(elm); break;
+		case HTML_DEL:      renderPseudoElement(":before", elm); break;
+		case HTML_DIV:      htmlDIV(elm); break;
+		case HTML_DL:       htmlDL(elm); break;
+		case HTML_DT:       htmlDT(elm); break;
+		case HTML_EM:       renderPseudoElement(":before", elm); break;
+		case HTML_FONT:     htmlFONT(elm); break;
+		case HTML_FORM:     htmlFORM(elm); break;
+		case HTML_H1://no-break
+		case HTML_H2://no-break
+		case HTML_H3://no-break
+		case HTML_H4://no-break
+		case HTML_H5://no-break
+		case HTML_H6:		htmlH(elm); break;
+		case HTML_HEAD:     htmlHEAD(elm); break;
+		case HTML_HR:       htmlHR(elm); break;
+		case HTML_HTML:     htmlHTML(elm); break;
+		case HTML_I:        htmlI(elm); break;
+		case HTML_IMG:      htmlIMG(elm); break;
+		case HTML_INPUT:    htmlINPUT(elm); break;
+		case HTML_LI:       htmlLI(elm); break;
+		case HTML_LUA:      htmlLUA(elm); break;
+		case HTML_META:     htmlMETA(elm); break;
+		case HTML_OBJECT:   htmlOBJECT(elm); break;
+		case HTML_OL:       htmlOL(elm); break;
+		case HTML_OPTION:   htmlOPTION(elm); break;
+		case HTML_P:        htmlP(elm); break;
+		case HTML_PRE:      htmlPRE(elm); break;
+		case HTML_SCRIPT:   htmlSCRIPT(elm); break;
+		case HTML_SELECT:   htmlSELECT(elm); break;
+		case HTML_SMALL:    renderPseudoElement(":before", elm); break;
+		case HTML_SPAN:     renderPseudoElement(":before", elm); break;
+		case HTML_STRONG:   renderPseudoElement(":before", elm); break;
+		case HTML_STYLE:    htmlSTYLE(elm); break;
+		case HTML_TABLE:    htmlTABLE(elm); break;
+		case HTML_TD:       htmlTD(elm); break;
+		case HTML_TEXTAREA: htmlTEXTAREA(elm); break;
+		case HTML_TH:       htmlTH(elm); break;
+		case HTML_TITLE:    htmlTITLE(elm); break;
+		case HTML_TR:       htmlTR(elm); break;
+		case HTML_U:        renderPseudoElement(":before", elm); break;
+		case HTML_UL:       htmlUL(elm); break;
+		default:
+			renderPseudoElement(":before", elm);
+			break;
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::endElement(CHtmlElement &elm)
+	{
+		_CurrentHTMLElement = &elm;
+
+		switch(elm.ID)
+		{
+		case HTML_A:        htmlAend(elm); break;
+		case HTML_BASE:     break;
+		case HTML_BODY:     renderPseudoElement(":after", elm); break;
+		case HTML_BR:       break;
+		case HTML_DD:       htmlDDend(elm); break;
+		case HTML_DEL:      renderPseudoElement(":after", elm); break;
+		case HTML_DIV:      htmlDIVend(elm); break;
+		case HTML_DL:       htmlDLend(elm); break;
+		case HTML_DT:       htmlDTend(elm); break;
+		case HTML_EM:       renderPseudoElement(":after", elm);break;
+		case HTML_FONT:     break;
+		case HTML_FORM:     renderPseudoElement(":after", elm);break;
+		case HTML_H1://no-break
+		case HTML_H2://no-break
+		case HTML_H3://no-break
+		case HTML_H4://no-break
+		case HTML_H5://no-break
+		case HTML_H6:		htmlHend(elm); break;
+		case HTML_HEAD:     htmlHEADend(elm); break;
+		case HTML_HR:       break;
+		case HTML_HTML:     break;
+		case HTML_I:        htmlIend(elm); break;
+		case HTML_IMG:      break;
+		case HTML_INPUT:    break;
+		case HTML_LI:       htmlLIend(elm); break;
+		case HTML_LUA:      htmlLUAend(elm); break;
+		case HTML_META:     break;
+		case HTML_OBJECT:   htmlOBJECTend(elm); break;
+		case HTML_OL:       htmlOLend(elm); break;
+		case HTML_OPTION:   htmlOPTIONend(elm); break;
+		case HTML_P:        htmlPend(elm); break;
+		case HTML_PRE:      htmlPREend(elm); break;
+		case HTML_SCRIPT:   htmlSCRIPTend(elm); break;
+		case HTML_SELECT:   htmlSELECTend(elm); break;
+		case HTML_SMALL:    renderPseudoElement(":after", elm);break;
+		case HTML_SPAN:     renderPseudoElement(":after", elm);break;
+		case HTML_STRONG:   renderPseudoElement(":after", elm);break;
+		case HTML_STYLE:    htmlSTYLEend(elm); break;
+		case HTML_TABLE:    htmlTABLEend(elm); break;
+		case HTML_TD:       htmlTDend(elm); break;
+		case HTML_TEXTAREA: htmlTEXTAREAend(elm); break;
+		case HTML_TH:       htmlTHend(elm); break;
+		case HTML_TITLE:    htmlTITLEend(elm); break;
+		case HTML_TR:       htmlTRend(elm); break;
+		case HTML_U:        renderPseudoElement(":after", elm); break;
+		case HTML_UL:       htmlULend(elm); break;
+		default:
+			renderPseudoElement(":after", elm);
+			break;
+		}
+
+
+		_Style.popStyle();
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::renderPseudoElement(const std::string &pseudo, const CHtmlElement &elm)
+	{
+		if (pseudo == ":before" && !elm.StyleBefore.empty())
+		{
+			_Style.pushStyle();
+			_Style.applyStyle(elm.StyleBefore);
+		}
+		else if (pseudo == ":after" && !elm.StyleAfter.empty())
+		{
+			_Style.pushStyle();
+			_Style.applyStyle(elm.StyleAfter);
+		}
+		else
+		{
+			// unknown pseudo element
+			return;
+		}
+
+		// TODO: 'content' should already be tokenized in css parser as it has all the functions for that
+		std::string content = trim(_Style.getStyle("content"));
+		if (toLower(content) == "none" || toLower(content) == "normal")
+		{
+			return;
+		}
+
+		// TODO: use ucstring / ucchar as content is utf8 chars
+		std::string::size_type pos = 0;
+		while(pos < content.size())
+		{
+			std::string::size_type start;
+			std::string token;
+		
+			// not supported
+			// counter, open-quote, close-quote, no-open-quote, no-close-quote
+			if (content[pos] == '"' || content[pos] == '\'')
+			{
+				char quote = content[pos];
+				pos++;
+				start = pos;
+				while(pos < content.size() && content[pos] != quote)
+				{
+					if (content[pos] == '\\') pos++;
+					pos++;
+				}
+				token = content.substr(start, pos - start);
+				addString(ucstring::makeFromUtf8(token));
+
+				// skip closing quote
+				pos++;
+			}
+			else if (content[pos] == 'u' && pos < content.size() - 6 && toLower(content.substr(pos, 4)) == "url(")
+			{
+				// url(/path-to/image.jpg) / "Alt!"
+				// url("/path to/image.jpg") / "Alt!"
+				std::string tooltip;
+
+				start = pos + 4;
+				// fails if url contains ')'
+				pos = content.find(")", start);
+				token = trim(content.substr(start, pos - start));
+				// skip ')'
+				pos++;
+
+				// scan for tooltip
+				start = pos;
+				while(pos < content.size() && content[pos] == ' ' && content[pos] != '/')
+				{
+					pos++;
+				}
+				if (pos < content.size() && content[pos] == '/')
+				{
+					// skip '/'
+					pos++;
+
+					// skip whitespace
+					while(pos < content.size() && content[pos] == ' ')
+					{
+						pos++;
+					}
+					if (pos < content.size() && (content[pos] == '\'' || content[pos] == '"'))
+					{
+						char openQuote =  content[pos];
+						pos++;
+						start = pos;
+						while(pos < content.size() && content[pos] != openQuote)
+						{
+							if (content[pos] == '\\') pos++;
+							pos++;
+						}
+						tooltip = content.substr(start, pos - start);
+
+						// skip closing quote
+						pos++;
+					}
+					else
+					{
+						// tooltip should be quoted
+						pos = start;
+						tooltip.clear();
+					}
+				}
+				else
+				{
+					// no tooltip
+					pos = start;
+				}
+
+				if (tooltip.empty())
+				{
+					addImage(getId() + pseudo, token, false, _Style.Current);
+				}
+				else
+				{
+					tooltip = trimQuotes(tooltip);
+					addButton(CCtrlButton::PushButton, getId() + pseudo, token, token, "", "", "", tooltip.c_str(), _Style.Current);
+				}
+			}
+			else if (content[pos] == 'a' && pos < content.size() - 7)
+			{
+				// attr(title)
+				start = pos + 5;
+				pos = content.find(")", start);
+				token = content.substr(start, pos - start);
+				// skip ')'
+				pos++;
+
+				if (elm.hasAttribute(token))
+				{
+					addString(ucstring::makeFromUtf8(elm.getAttribute(token)));
+				}
+			}
+			else
+			{
+				pos++;
+			}
+		}
+
+		_Style.popStyle();
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::renderDOM(CHtmlElement &elm)
+	{
+		if (elm.Type == CHtmlElement::TEXT_NODE)
+		{
+			addText(elm.Value.c_str(), elm.Value.size());
+		}
+		else
+		{
+			beginElement(elm);
+
+			std::list<CHtmlElement>::iterator it = elm.Children.begin();
+			while(it != elm.Children.end())
+			{
+				renderDOM(*it);
+
+				++it;
+			}
+
+			endElement(elm);
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::beginElementDeprecated(uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value)
 	{
 		if (_Browsing)
 		{
@@ -1229,8 +1578,6 @@ namespace NLGUI
 				_Style.Current.TextColor = LinkColor;
 				_Style.Current.Underlined = true;
 				_Style.Current.GlobalColor = LinkColorGlobalColor;
-				_Style.Current.BackgroundColor.A = 0;
-				_Style.Current.BackgroundColorOver.A = 0;
 				_Style.Current.Width = -1;
 				_Style.Current.Height = -1;
 
@@ -1638,10 +1985,6 @@ namespace NLGUI
 						_Style.Current.TextShadow = CStyleParams::STextShadow(true);
 						_Style.Current.Width = -1;
 						_Style.Current.Height = -1;
-						// by default background texture is transparent,
-						// using alpha value to decide if to change it to 'blank.tga' for coloring
-						_Style.Current.BackgroundColor.A = 0;
-						_Style.Current.BackgroundColorOver.A = 0;
 
 						// Global color flag
 						if (present[MY_HTML_INPUT_GLOBAL_COLOR])
@@ -2024,7 +2367,7 @@ namespace NLGUI
 					registerAnchorName(MY_HTML_TABLE);
 
 					// Get cells parameters
-					getCellsParameters (MY_HTML_TABLE, false);
+					getCellsParameters_DEP (MY_HTML_TABLE, false);
 
 					CGroupTable *table = new CGroupTable(TCtorParam());
 					table->BgColor = _CellParams.back().BgColor;
@@ -2058,7 +2401,7 @@ namespace NLGUI
 			case HTML_TD:
 				{
 					// Get cells parameters
-					getCellsParameters (MY_HTML_TD, true);
+					getCellsParameters_DEP (MY_HTML_TD, true);
 
 					_Style.pushStyle();
 					if (element_number == HTML_TH)
@@ -2162,7 +2505,6 @@ namespace NLGUI
 				_Style.Current.TextShadow = CStyleParams::STextShadow(true);
 				_Style.Current.Width = -1;
 				_Style.Current.Height = -1;
-				_Style.Current.BackgroundColor.A = 0;
 
 				if (present[MY_HTML_TEXTAREA_STYLE] && value[MY_HTML_TEXTAREA_STYLE])
 					_Style.applyStyle(value[MY_HTML_TEXTAREA_STYLE]);
@@ -2213,7 +2555,7 @@ namespace NLGUI
 			case HTML_TR:
 				{
 					// Get cells parameters
-					getCellsParameters (MY_HTML_TR, true);
+					getCellsParameters_DEP (MY_HTML_TR, true);
 
 					// Set TR flag
 					if (!_TR.empty())
@@ -2441,7 +2783,7 @@ namespace NLGUI
 
 	// ***************************************************************************
 
-	void CGroupHTML::endElement (uint element_number)
+	void CGroupHTML::endElementDeprecated(uint element_number)
 	{
 		if (_Browsing)
 		{
@@ -2733,35 +3075,6 @@ namespace NLGUI
 		}
 	}
 
-	// ***************************************************************************
-	void CGroupHTML::beginUnparsedElement(const char *buffer, int length)
-	{
-		string str(buffer, buffer+length);
-		if (stricmp(str.c_str(), "lua") == 0)
-		{
-			// we receive an embeded lua script
-			_ParsingLua = _TrustedDomain; // Only parse lua if TrustedDomain
-			_LuaScript.clear();
-		}
-	}
-
-	// ***************************************************************************
-	void CGroupHTML::endUnparsedElement(const char *buffer, int length)
-	{
-		string str(buffer, buffer+length);
-		if (stricmp(str.c_str(), "lua") == 0)
-		{
-			if (_ParsingLua && _TrustedDomain)
-			{
-				_ParsingLua = false;
-				// execute the embeded lua script
-				_LuaScript = "\nlocal __CURRENT_WINDOW__=\""+this->_Id+"\" \n"+_LuaScript;
-				CLuaManager::getInstance().executeLuaScript(_LuaScript, true);
-			}
-		}
-	}
-
-
 	// ***************************************************************************
 	NLMISC_REGISTER_OBJECT(CViewBase, CGroupHTML, std::string, "html");
 
@@ -2775,7 +3088,8 @@ namespace NLGUI
 	CGroupHTML::CGroupHTML(const TCtorParam &param)
 	:	CGroupScrollText(param),
 		_TimeoutValue(DEFAULT_RYZOM_CONNECTION_TIMEOUT),
-		_RedirectsRemaining(DEFAULT_RYZOM_REDIRECT_LIMIT)
+		_RedirectsRemaining(DEFAULT_RYZOM_REDIRECT_LIMIT),
+		_CurrentHTMLElement(NULL)
 	{
 		// add it to map of group html created
 		_GroupHtmlUID= ++_GroupHtmlUIDPool; // valid assigned Id begin to 1!
@@ -2800,6 +3114,8 @@ namespace NLGUI
 		_RefreshUrl.clear();
 		_NextRefreshTime = 0.0;
 		_LastRefreshTime = 0.0;
+		_RenderNextTime = false;
+		_WaitingForStylesheet = false;
 
 		// Register
 		CWidgetManager::getInstance()->registerClockMsgTarget(this);
@@ -4248,7 +4564,7 @@ namespace NLGUI
 
 	// ***************************************************************************
 
-	void CGroupHTML::addImage(const std::string &id, const char *img, bool reloadImg, const CStyleParams &style)
+	void CGroupHTML::addImage(const std::string &id, const std::string &img, bool reloadImg, const CStyleParams &style)
 	{
 		// In a paragraph ?
 		if (!_Paragraph)
@@ -4377,7 +4693,7 @@ namespace NLGUI
 				if (eb)
 				{
 					eb->setInputString(decodeHTMLEntities(content));
-					if (style.BackgroundColor.A > 0)
+					if (style.hasStyle("background-color"))
 					{
 						CViewBitmap *bg = dynamic_cast<CViewBitmap*>(eb->getView("bg"));
 						if (bg)
@@ -4613,6 +4929,8 @@ namespace NLGUI
 
 	void CGroupHTML::clearContext()
 	{
+		_CurrentHTMLElement = NULL;
+		_CurrentHTMLNextSibling = NULL;
 		_Paragraph = NULL;
 		_PRE.clear();
 		_Indent.clear();
@@ -4959,6 +5277,17 @@ namespace NLGUI
 			}
 		}
 		else
+		if (_RenderNextTime)
+		{
+			_RenderNextTime = false;
+			renderHtmlString(_DocumentHtml);
+		}
+		else
+		if (_WaitingForStylesheet)
+		{
+			renderDocument();
+		}
+		else
 		if (_BrowseNextTime || _PostNextTime)
 		{
 			// Set timeout
@@ -5353,21 +5682,45 @@ namespace NLGUI
 	}
 
 	// ***************************************************************************
-
-	bool CGroupHTML::renderHtmlString(const std::string &html)
+	void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local)
 	{
-		bool success;
+		// remove from queue
+		std::vector<std::string>::iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url);
+		if (it != _StylesheetQueue.end())
+		{
+			_StylesheetQueue.erase(it);
+		}
+
+		if (!CFile::fileExists(local))
+		{
+			return;
+		}
+
+		parseStylesheetFile(local);
+	}
+
+	void CGroupHTML::renderDocument()
+	{
+		if (!_StylesheetQueue.empty())
+		{
+			// waiting for stylesheets to finish downloading
+			return;
+		}
+
+		//TGameTime renderStart = CTime::getLocalTime();
 
-		//
 		_Browsing = true;
-		_DocumentUrl = _URL;
-		_NextRefreshTime = 0;
-		_RefreshUrl.clear();
+		_WaitingForStylesheet = false;
 
-		// clear content
-		beginBuild();
-
-		success = parseHtml(html);
+		// keeps track of currently rendered element
+		_CurrentHTMLElement = NULL;
+		std::list<CHtmlElement>::iterator it = _HtmlDOM.Children.begin();
+		while(it != _HtmlDOM.Children.end())
+		{
+			renderDOM(*it);
+			++it;
+		}
+		_CurrentHTMLElement = NULL;
 
 		// invalidate coords
 		endBuild();
@@ -5383,11 +5736,64 @@ namespace NLGUI
 			setTitle(_TitlePrefix);
 		}
 
-		return success;
+		//TGameTime renderStop = CTime::getLocalTime();
+		//nlwarning("[%s] render: %.1fms (%s)\n", _Id.c_str(), (renderStop - renderStart), _URL.c_str());
 	}
 
 	// ***************************************************************************
 
+	bool CGroupHTML::renderHtmlString(const std::string &html)
+	{
+		bool success;
+
+		// if we are already rendering, then queue up the next page
+		if (_CurrentHTMLElement)
+		{
+			_DocumentHtml = html;
+			_RenderNextTime = true;
+
+			return true;
+		}
+
+		//
+		_Browsing = true;
+		_DocumentUrl = _URL;
+		_DocumentHtml = html;
+		_NextRefreshTime = 0;
+		_RefreshUrl.clear();
+
+		// clear content
+		beginBuild();
+		resetCssStyle();
+
+		// start new rendering
+		_HtmlDOM = CHtmlElement(CHtmlElement::NONE, "<root>");
+
+		if (!trim(html).empty())
+		{
+			success = parseHtml(html);
+			if (success)
+			{
+				_WaitingForStylesheet = !_StylesheetQueue.empty();
+				renderDocument();
+			}
+			else
+			{
+				std::string error = "ERROR: HTML parse failed.";
+				error += toString("\nsize %d bytes", html.size());
+				error += toString("\n---start---\n%s\n---end---\n", html.c_str());
+				browseError(error.c_str());
+			}
+		}
+
+		endBuild();
+		updateRefreshButton();
+		_Browsing = false;
+
+		return success;
+	}
+
+	// ***************************************************************************
 	void CGroupHTML::doBrowseAnchor(const std::string &anchor)
 	{
 		if (_Anchors.count(anchor) == 0)
@@ -5832,8 +6238,11 @@ namespace NLGUI
 	}
 
 	// ***************************************************************************
+	// @deprecated
 	int CGroupHTML::luaBeginElement(CLuaState &ls)
 	{
+		nlwarning("Deprecated luaBeginElement on url '%s'", _URL.c_str());
+
 		const char *funcName = "beginElement";
 		CLuaIHM::checkArgCount(ls, funcName, 2);
 		CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
@@ -5877,7 +6286,7 @@ namespace NLGUI
 		// ingame lua scripts from browser are using <a href="#http://..."> url scheme
 		// reason unknown
 		_LuaHrefHack = true;
-		beginElement(element_number, present, value);
+		beginElementDeprecated(element_number, present, value);
 		_LuaHrefHack = false;
 
 		return 0;
@@ -5885,6 +6294,7 @@ namespace NLGUI
 
 
 	// ***************************************************************************
+	// @deprecated
 	int CGroupHTML::luaEndElement(CLuaState &ls)
 	{
 		const char *funcName = "endElement";
@@ -5892,7 +6302,7 @@ namespace NLGUI
 		CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
 
 		uint element_number = (uint)ls.toInteger(1);
-		endElement(element_number);
+		endElementDeprecated(element_number);
 
 		return 0;
 	}
@@ -5926,16 +6336,157 @@ namespace NLGUI
 		browse(url.c_str());
 	}
 
+	// ***************************************************************************
+	void CGroupHTML::parseStylesheetFile(const std::string &fname)
+	{
+		CIFile css;
+		if (css.open(fname))
+		{
+			uint32 remaining = css.getFileSize();
+			std::string content;
+			try {
+				while(!css.eof() && remaining > 0)
+				{
+					const uint BUF_SIZE = 4096;
+					char buf[BUF_SIZE];
+
+					uint32 readJustNow = std::min(remaining, BUF_SIZE);
+					css.serialBuffer((uint8 *)&buf, readJustNow);
+					content.append(buf, readJustNow);
+					remaining -= readJustNow;
+				}
+
+				_Style.parseStylesheet(content);
+			}
+			catch(const Exception &e)
+			{
+				nlwarning("exception while reading css file '%s'", e.what());
+			}
+		}
+		else
+		{
+			nlwarning("Stylesheet file '%s' not found (%s)", fname.c_str(), _URL.c_str());
+		}
+	}
+
 	// ***************************************************************************
 	bool CGroupHTML::parseHtml(const std::string &htmlString)
 	{
-		CHtmlParser html(this);
+		std::vector<std::string> links;
+		std::string styleString;
 
-		bool result = html.parseHtml(htmlString);
-		if (result)
-			_DocumentHtml = htmlString;
+		CHtmlElement *parsedDOM;
+		if (_CurrentHTMLElement == NULL)
+		{
+			// parse under <root> element (clean dom)
+			parsedDOM = &_HtmlDOM;
+		}
+		else
+		{
+			// parse under currently rendered <lua> element
+			parsedDOM = _CurrentHTMLElement;
+		}
 
-		return result;
+		CHtmlParser parser;
+		parser.getDOM(htmlString, *parsedDOM, styleString, links);
+
+		if (!styleString.empty())
+		{
+			_Style.parseStylesheet(styleString);
+		}
+		if (!links.empty())
+		{
+			addStylesheetDownload(links);
+		}
+
+		// this should rarely fail as first element should be <html>
+		bool success = parsedDOM->Children.size() > 0;
+
+		std::list<CHtmlElement>::iterator it = parsedDOM->Children.begin();
+		while(it != parsedDOM->Children.end())
+		{
+			if (it->Type == CHtmlElement::ELEMENT_NODE && it->Value == "html")
+			{
+				// more newly parsed childs from <body> into siblings
+				if (_CurrentHTMLElement) {
+					std::list<CHtmlElement>::iterator it2 = it->Children.begin();
+					while(it2 != it->Children.end())
+					{
+						if (it2->Type == CHtmlElement::ELEMENT_NODE && it2->Value == "body")
+						{
+							spliceFragment(it2);
+							break;
+						}
+						++it2;
+					}
+					// remove <html> fragment from current element child
+					it = parsedDOM->Children.erase(it);
+				}
+				else
+				{
+					// remove link to <root> (html->parent == '<root>') or css selector matching will break
+					it->parent = NULL;
+					++it;
+				}
+				continue;
+			}
+
+			// skip over other non-handled element
+			++it;
+		}
+
+		return success;
+	}
+
+	void CGroupHTML::spliceFragment(std::list<CHtmlElement>::iterator src)
+	{
+		if(!_CurrentHTMLElement->parent)
+		{
+			nlwarning("BUG: Current node is missing parent element. unable to splice fragment");
+			return;
+		}
+
+		// get the iterators for current element (<lua>) and next sibling
+		std::list<CHtmlElement>::iterator currentElement;
+		currentElement = std::find(_CurrentHTMLElement->parent->Children.begin(), _CurrentHTMLElement->parent->Children.end(), *_CurrentHTMLElement);
+		if (currentElement == _CurrentHTMLElement->parent->Children.end())
+		{
+			nlwarning("BUG: unable to find current element iterator from parent");
+			return;
+		}
+		
+		// where fragment should be moved
+		std::list<CHtmlElement>::iterator insertBefore;
+		if (_CurrentHTMLNextSibling == NULL)
+		{
+			insertBefore = _CurrentHTMLElement->parent->Children.end();
+		} else {
+			// get iterator for nextSibling
+			insertBefore = std::find(_CurrentHTMLElement->parent->Children.begin(), _CurrentHTMLElement->parent->Children.end(), *_CurrentHTMLNextSibling);
+		}
+
+		_CurrentHTMLElement->parent->Children.splice(insertBefore, src->Children);
+
+		// reindex moved elements
+		CHtmlElement *prev = NULL;
+		uint childIndex = _CurrentHTMLElement->childIndex;
+		while(currentElement != _CurrentHTMLElement->parent->Children.end())
+		{
+			if (currentElement->Type == CHtmlElement::ELEMENT_NODE)
+			{
+				if (prev != NULL)
+				{
+					currentElement->parent = _CurrentHTMLElement->parent;
+					currentElement->childIndex = childIndex;
+					currentElement->previousSibling = prev;
+					prev->nextSibling = &(*currentElement);
+				}
+
+				childIndex++;
+				prev = &(*currentElement);
+			}
+			++currentElement;
+		}
 	}
 
 	// ***************************************************************************
@@ -6039,11 +6590,38 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::resetCssStyle()
 	{
+		_WaitingForStylesheet = false;
+		_StylesheetQueue.clear();
+
+		std::string css;
+
+		// TODO: browser css
+		css += "html { background-color: " + getRGBAString(BgColor) + "; color: " + getRGBAString(TextColor) + "; font-size: " + toString(TextFontSize) + "px;}";
+		css += "a { color: " + getRGBAString(LinkColor) + "; text-decoration: underline; -ryzom-modulate-color: "+toString(LinkColorGlobalColor)+";}";
+		css += "h1 { color: " + getRGBAString(H1Color) + "; font-size: "+ toString("%d", H1FontSize) + "px; -ryzom-modulate-color: "+toString(H1ColorGlobalColor)+";}";
+		css += "h2 { color: " + getRGBAString(H2Color) + "; font-size: "+ toString("%d", H2FontSize) + "px; -ryzom-modulate-color: "+toString(H2ColorGlobalColor)+";}";
+		css += "h3 { color: " + getRGBAString(H3Color) + "; font-size: "+ toString("%d", H3FontSize) + "px; -ryzom-modulate-color: "+toString(H3ColorGlobalColor)+";}";
+		css += "h4 { color: " + getRGBAString(H4Color) + "; font-size: "+ toString("%d", H4FontSize) + "px; -ryzom-modulate-color: "+toString(H4ColorGlobalColor)+";}";
+		css += "h5 { color: " + getRGBAString(H5Color) + "; font-size: "+ toString("%d", H5FontSize) + "px; -ryzom-modulate-color: "+toString(H5ColorGlobalColor)+";}";
+		css += "h6 { color: " + getRGBAString(H6Color) + "; font-size: "+ toString("%d", H6FontSize) + "px; -ryzom-modulate-color: "+toString(H6ColorGlobalColor)+";}";
+		css += "input[type=\"text\"] { color: " + getRGBAString(TextColor) + "; font-size: " + toString("%d", TextFontSize) + "px; font-weight: normal; text-shadow: 1px 1px #000;}";
+		css += "pre { font-family: monospace;}";
+		// th { text-align: center; } - overwrites align property
+		css += "th { font-weight: bold; }";
+		css += "textarea { color: " + getRGBAString(TextColor) + "; font-weight: normal; font-size: " + toString("%d", TextFontSize) + "px; text-shadow: 1px 1px #000;}";
+		css += "del { text-decoration: line-through;}";
+		css += "u { text-decoration: underline;}";
+		css += "em { font-style: italic; }";
+		css += "strong { font-weight: bold; }";
+		css += "small { font-size: smaller;}";
+		css += "dt { font-weight: bold; }";
+		css += "hr { color: rgb(120, 120, 120);}";
+		// td { padding: 1px;} - overwrites cellpadding attribute
+		// table { border-spacing: 2px;} - overwrites cellspacing attribute
+		css += "table { border-collapse: separate;}";
+
 		_Style.reset();
-		_Style.Root.TextColor = TextColor;
-		_Style.Root.FontSize = TextFontSize;
-		_Style.Root.BackgroundColor = BgColor;
-		_Style.Current = _Style.Root;
+		_Style.parseStylesheet(css);
 	}
 	
 	// ***************************************************************************
@@ -6147,5 +6725,1519 @@ namespace NLGUI
 		return ret;
 	}
 
+	void CGroupHTML::getCellsParameters(const CHtmlElement &elm, bool inherit)
+	{
+		CGroupHTML::CCellParams cellParams;
+		if (!_CellParams.empty() && inherit)
+		{
+			cellParams = _CellParams.back();
+		}
+
+		if (_Style.hasStyle("background-color"))
+			cellParams.BgColor = _Style.Current.BackgroundColor;
+		else if (elm.hasNonEmptyAttribute("bgcolor"))
+			scanHTMLColor(elm.getAttribute("bgcolor").c_str(), cellParams.BgColor);
+
+		if (elm.hasAttribute("nowrap") || _Style.Current.WhiteSpace == "nowrap")
+			cellParams.NoWrap = true;
+
+		if (elm.hasNonEmptyAttribute("l_margin"))
+			fromString(elm.getAttribute("l_margin"), cellParams.LeftMargin);
+
+		{
+			std::string align;
+			// having text-align on table/tr should not override td align attribute
+			if (_Style.hasStyle("text-align"))
+				align = _Style.Current.TextAlign;
+			else if (elm.hasNonEmptyAttribute("align"))
+				align = toLower(elm.getAttribute("align"));
+
+			if (align == "left")
+				cellParams.Align = CGroupCell::Left;
+			else if (align == "center")
+				cellParams.Align = CGroupCell::Center;
+			else if (align == "right")
+				cellParams.Align = CGroupCell::Right;
+		}
+
+		{
+			std::string valign;
+			if (_Style.hasStyle("vertical-align"))
+				valign = _Style.Current.VerticalAlign;
+			else if (elm.hasNonEmptyAttribute("valign"))
+				valign = toLower(elm.getAttribute("valign"));
+			
+			if (valign == "top")
+				cellParams.VAlign = CGroupCell::Top;
+			else if (valign == "middle")
+				cellParams.VAlign = CGroupCell::Middle;
+			else if (valign == "bottom")
+				cellParams.VAlign = CGroupCell::Bottom;
+		}
+		
+		_CellParams.push_back (cellParams);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlA(const CHtmlElement &elm)
+	{
+		_A.push_back(true);
+		_Link.push_back ("");
+		_LinkTitle.push_back("");
+		_LinkClass.push_back("");
+		if (elm.hasClass("ryzom-ui-button"))
+			_LinkClass.back() = "ryzom-ui-button";
+
+		// #fragment works with both ID and NAME so register both
+		if (elm.hasNonEmptyAttribute("name"))
+			_AnchorName.push_back(elm.getAttribute("name"));
+		if (elm.hasNonEmptyAttribute("title"))
+			_LinkTitle.back() = elm.getAttribute("title");
+		if (elm.hasNonEmptyAttribute("href"))
+		{
+			string suri = elm.getAttribute("href");
+			if(suri.find("ah:") == 0)
+			{
+				if (_TrustedDomain)
+					_Link.back() = suri;
+			}
+			else if (_TrustedDomain && suri[0] == '#' && _LuaHrefHack)
+			{
+				// Direct url (hack for lua beginElement)
+				_Link.back() = suri.substr(1);
+			}
+			else
+			{
+				// convert href from "?key=val" into "http://domain.com/?key=val"
+				_Link.back() = getAbsoluteUrl(suri);
+			}
+		}
+
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlAend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+
+		popIfNotEmpty(_A);
+		popIfNotEmpty(_Link);
+		popIfNotEmpty(_LinkTitle);
+		popIfNotEmpty(_LinkClass);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlBASE(const CHtmlElement &elm)
+	{
+		if (!_ReadingHeadTag || _IgnoreBaseUrlTag)
+			return;
+
+		if (elm.hasNonEmptyAttribute("href"))
+		{
+			CUrlParser uri(elm.getAttribute("href"));
+			if (uri.isAbsolute())
+			{
+				_URL = uri.toString();
+				_IgnoreBaseUrlTag = true;
+			}
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlBODY(const CHtmlElement &elm)
+	{
+		// override <body> (or <html>) css style attribute
+		if (elm.hasNonEmptyAttribute("bgcolor"))
+		{
+			_Style.applyStyle("background-color: " + elm.getAttribute("bgcolor"));
+		}
+
+		if (_Style.hasStyle("background-color"))
+		{
+			CRGBA bgColor = _Style.Current.BackgroundColor;
+			scanHTMLColor(elm.getAttribute("bgcolor").c_str(), bgColor);
+			setBackgroundColor(bgColor);
+		}
+
+		if (elm.hasNonEmptyAttribute("style"))
+		{
+			string style = elm.getAttribute("style");
+
+			TStyle styles = parseStyle(style);
+			TStyle::iterator	it;
+
+			it = styles.find("background-repeat");
+			bool repeat = (it != styles.end() && it->second == "1");
+
+			// Webig only
+			it = styles.find("background-scale");
+			bool scale = (it != styles.end() && it->second == "1");
+
+			it = styles.find("background-image");
+			if (it != styles.end())
+			{
+				string image = it->second;
+				string::size_type texExt = toLower(image).find("url(");
+				// Url image
+				if (texExt != string::npos)
+					// Remove url()
+					image = image.substr(4, image.size()-5);
+				setBackground (image, scale, repeat);
+			}
+		}
+
+		renderPseudoElement(":before", elm);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlBR(const CHtmlElement &elm)
+	{
+		endParagraph();
+
+		// insert zero-width-space (0x200B) to prevent removal of empty lines
+		ucstring tmp;
+		tmp.fromUtf8("\xe2\x80\x8b");
+		addString(tmp);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlDD(const CHtmlElement &elm)
+	{
+		if (_DL.empty())
+			return;
+
+		// if there was no closing tag for <dt>, then remove <dt> style
+		if (_DL.back().DT)
+		{
+			nlwarning("BUG: nested DT in DD");
+			_DL.back().DT = false;
+		}
+
+		if (_DL.back().DD)
+		{
+			nlwarning("BUG: nested DD in DD");
+			_DL.back().DD = false;
+			popIfNotEmpty(_Indent);
+		}
+
+		_DL.back().DD = true;
+		_Indent.push_back(getIndent() + ULIndent);
+
+		if (!_LI)
+		{
+			_LI = true;
+			newParagraph(ULBeginSpace);
+		}
+		else
+		{
+			newParagraph(LIBeginSpace);
+		}
+
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlDDend(const CHtmlElement &elm)
+	{
+		if (_DL.empty())
+			return;
+
+		renderPseudoElement(":after", elm);
+
+		// parser will process two DD in a row as nested when first DD is not closed
+		if (_DL.back().DD)
+		{
+			_DL.back().DD = false;
+			popIfNotEmpty(_Indent);
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlDIV(const CHtmlElement &elm)
+	{
+		_BlockLevelElement.push_back(true);
+
+		_DivName = elm.getAttribute("name");
+
+		string instClass = elm.getAttribute("class");
+
+		// use generic template system
+		if (_TrustedDomain && !instClass.empty() && instClass == "ryzom-ui-grouptemplate")
+		{
+			string style = elm.getAttribute("style");
+			string id = elm.getAttribute("id");
+
+			typedef pair<string, string> TTmplParam;
+			vector<TTmplParam> tmplParams;
+
+			string templateName;
+			if (!style.empty())
+			{
+				TStyle styles = parseStyle(style);
+				TStyle::iterator	it;
+				for (it=styles.begin(); it != styles.end(); it++)
+				{
+					if ((*it).first == "template")
+						templateName = (*it).second;
+					else if ((*it).first == "display" && (*it).second == "inline-block")
+						_BlockLevelElement.back() = false;
+					else
+						tmplParams.push_back(TTmplParam((*it).first, (*it).second));
+				}
+			}
+
+			if (!templateName.empty())
+			{
+				string parentId;
+				bool haveParentDiv = getDiv() != NULL;
+				if (haveParentDiv)
+					parentId = getDiv()->getId();
+				else
+				{
+					if (!_Paragraph)
+						newParagraph (0);
+
+					parentId = _Paragraph->getId();
+				}
+
+				CInterfaceGroup *inst = CWidgetManager::getInstance()->getParser()->createGroupInstance(templateName, this->_Id+":"+id, tmplParams);
+				if (inst)
+				{
+					inst->setId(this->_Id+":"+id);
+					inst->updateCoords();
+					if (haveParentDiv)
+					{
+							inst->setParent(getDiv());
+							inst->setParentSize(getDiv());
+							inst->setParentPos(getDiv());
+							inst->setPosRef(Hotspot_TL);
+							inst->setParentPosRef(Hotspot_TL);
+							getDiv()->addGroup(inst);
+
+							_BlockLevelElement.back() = false;
+					}
+					else
+					{
+						getParagraph()->addChild(inst);
+						paragraphChange();
+					}
+					_Divs.push_back(inst);
+				}
+			}
+		}
+
+		if (isBlockLevelElement())
+		{
+			newParagraph(0);
+		}
+
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlDIVend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+
+		if (isBlockLevelElement())
+		{
+			endParagraph();
+		}
+		_DivName.clear();
+		popIfNotEmpty(_Divs);
+		popIfNotEmpty(_BlockLevelElement);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlDL(const CHtmlElement &elm)
+	{
+		_DL.push_back(HTMLDListElement());
+		_LI = _DL.size() > 1 || !_UL.empty();
+		endParagraph();
+
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlDLend(const CHtmlElement &elm)
+	{
+		if (_DL.empty())
+			return;
+
+		renderPseudoElement(":after", elm);
+
+		endParagraph();
+
+		// unclosed DT
+		if (_DL.back().DT)
+		{
+			nlwarning("BUG: unclosed DT in DL");
+		}
+
+		// unclosed DD
+		if (_DL.back().DD)
+		{
+			popIfNotEmpty(_Indent);
+			nlwarning("BUG: unclosed DD in DL");
+		}
+
+		popIfNotEmpty (_DL);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlDT(const CHtmlElement &elm)
+	{
+		if (_DL.empty())
+			return;
+
+		// TODO: check if nested tags still happen and fix it in parser
+		//     : remove special handling for nesting and let it happen
+
+		// html parser and libxml2 should prevent nested tags like these
+		if (_DL.back().DD)
+		{
+			nlwarning("BUG: nested DD in DT");
+
+			_DL.back().DD = false;
+			popIfNotEmpty(_Indent);
+		}
+
+		// html parser and libxml2 should prevent nested tags like these
+		if (_DL.back().DT)
+		{
+			nlwarning("BUG: nested DT in DT");
+		}
+
+		_DL.back().DT = true;
+
+		if (!_LI)
+		{
+			_LI = true;
+			newParagraph(ULBeginSpace);
+		}
+		else
+		{
+			newParagraph(LIBeginSpace);
+		}
+		
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlDTend(const CHtmlElement &elm)
+	{
+		if (_DL.empty())
+			return;
+
+		renderPseudoElement(":after", elm);
+
+		_DL.back().DT = false;
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlFONT(const CHtmlElement &elm)
+	{
+		if (elm.hasNonEmptyAttribute("color"))
+		{
+			CRGBA color;
+			if (scanHTMLColor(elm.getAttribute("color").c_str(), color))
+				_Style.Current.TextColor = color;
+		}
+
+		if (elm.hasNonEmptyAttribute("size"))
+		{
+			uint fontsize;
+			fromString(elm.getAttribute("size"), fontsize);
+			_Style.Current.FontSize = fontsize;
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlFORM(const CHtmlElement &elm)
+	{
+		// Build the form
+		CGroupHTML::CForm form;
+
+		// Get the action name
+		if (elm.hasNonEmptyAttribute("action"))
+		{
+			form.Action = getAbsoluteUrl(elm.getAttribute("action"));
+		}
+		else
+		{
+			form.Action = _URL;
+		}
+
+		_Forms.push_back(form);
+
+		renderPseudoElement(":before", elm);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlH(const CHtmlElement &elm)
+	{
+		newParagraph(PBeginSpace);
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlHend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+		endParagraph();
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlHEAD(const CHtmlElement &elm)
+	{
+		_ReadingHeadTag = !_IgnoreHeadTag;
+		_IgnoreHeadTag = true;
+	}
+
+	void CGroupHTML::htmlHEADend(const CHtmlElement &elm)
+	{
+		_ReadingHeadTag = false;
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlHR(const CHtmlElement &elm)
+	{
+		newParagraph(0);
+
+		CInterfaceGroup *sep = CWidgetManager::getInstance()->getParser()->createGroupInstance("html_hr", "", NULL, 0);
+		if (sep)
+		{
+			CViewBitmap *bitmap = dynamic_cast<CViewBitmap*>(sep->getView("hr"));
+			if (bitmap)
+			{
+				bitmap->setColor(_Style.Current.TextColor);
+				if (_Style.Current.Width > 0)
+				{
+					clamp(_Style.Current.Width, 1, 32000);
+					bitmap->setW(_Style.Current.Width);
+					bitmap->setSizeRef(CInterfaceElement::none);
+				}
+				if (_Style.Current.Height > 0)
+				{
+					clamp(_Style.Current.Height, 1, 1000);
+					bitmap->setH(_Style.Current.Height);
+				}
+			}
+
+			renderPseudoElement(":before", elm);
+			getParagraph()->addChild(sep);
+			renderPseudoElement(":after", elm);
+
+			endParagraph();
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlHTML(const CHtmlElement &elm)
+	{
+		if (elm.hasNonEmptyAttribute("style"))
+		{
+			_Style.Root = _Style.Current;
+			_Style.applyRootStyle(elm.getAttribute("style"));
+			_Style.Current = _Style.Root;
+		}
+		setBackgroundColor(_Style.Current.BackgroundColor);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlI(const CHtmlElement &elm)
+	{
+		_Localize = true;
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlIend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+		_Localize = false;
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlIMG(const CHtmlElement &elm)
+	{
+		// Get the string name
+		if (elm.hasNonEmptyAttribute("src"))
+		{
+			float tmpf;
+			std::string id = elm.getAttribute("id");
+			std::string src = elm.getAttribute("src");
+
+			if (elm.hasNonEmptyAttribute("width"))
+				getPercentage(_Style.Current.Width, tmpf, elm.getAttribute("width").c_str());
+			if (elm.hasNonEmptyAttribute("height"))
+				getPercentage(_Style.Current.Height, tmpf, elm.getAttribute("height").c_str());
+
+			// Get the global color name
+			if (elm.hasAttribute("global_color"))
+				_Style.Current.GlobalColor = true;
+
+			// Tooltip
+			// keep "alt" attribute for backward compatibility
+			std::string strtooltip = elm.getAttribute("alt");
+			// tooltip
+			if (elm.hasNonEmptyAttribute("title"))
+				strtooltip = elm.getAttribute("title");
+
+			const char *tooltip = NULL;
+			// note: uses pointer to string data
+			if (!strtooltip.empty())
+				tooltip = strtooltip.c_str();
+
+			// Mouse over image
+			string overSrc = elm.getAttribute("data-over-src");
+
+			if (getA() && getParent () && getParent ()->getParent())
+			{
+				string params = "name=" + getId() + "|url=" + getLink ();
+				addButton(CCtrlButton::PushButton, id, src, src, overSrc, "browse", params.c_str(), tooltip, _Style.Current);
+			}
+			else
+			if (tooltip || !overSrc.empty())
+			{
+				addButton(CCtrlButton::PushButton, id, src, src, overSrc, "", "", tooltip, _Style.Current);
+			}
+			else
+			{
+				// Get the option to reload (class==reload)
+				bool reloadImg = false;
+
+				if (elm.hasNonEmptyAttribute("style"))
+				{
+					string styleString = elm.getAttribute("style");
+					TStyle styles = parseStyle(styleString);
+					TStyle::iterator	it;
+
+					it = styles.find("reload");
+					if (it != styles.end() && (*it).second == "1")
+						reloadImg = true;
+				}
+
+				addImage(id, elm.getAttribute("src"), reloadImg, _Style.Current);
+			}
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlINPUT(const CHtmlElement &elm)
+	{
+		if (_Forms.empty())
+			return;
+
+		// read general property
+		string id = elm.getAttribute("id");
+
+		// Widget template name (old)
+		string templateName = elm.getAttribute("z_btn_tmpl");
+		// Input name is the new
+		if (elm.hasNonEmptyAttribute("z_input_tmpl"))
+			templateName = elm.getAttribute("z_input_tmpl");
+
+		// Widget minimal width
+		string minWidth = elm.getAttribute("z_input_width");
+
+		// Get the type
+		if (elm.hasNonEmptyAttribute("type"))
+		{
+			// Global color flag
+			if (elm.hasAttribute("global_color"))
+				_Style.Current.GlobalColor = true;
+
+			// Tooltip
+			std::string strtooltip = elm.getAttribute("alt");
+			const char *tooltip = NULL;
+			// note: uses pointer to strtooltip data
+			if (!strtooltip.empty())
+				tooltip = strtooltip.c_str();
+
+			string type = toLower(elm.getAttribute("type"));
+			if (type == "image")
+			{
+				// The submit button
+				string name = elm.getAttribute("name");
+				string normal = elm.getAttribute("src");
+				string pushed;
+				string over;
+
+				// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
+				string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=image";
+
+				// Add the ctrl button
+				addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
+					"html_submit_form", param.c_str(), tooltip, _Style.Current);
+			}
+			else if (type == "button" || type == "submit")
+			{
+				// The submit button
+				string name = elm.getAttribute("name");
+				string normal = elm.getAttribute("src");
+				string text = elm.getAttribute("value");
+				string pushed;
+				string over;
+
+				string buttonTemplate(!templateName.empty() ? templateName : DefaultButtonGroup );
+
+				// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
+				string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=submit";
+				if (!text.empty())
+				{
+					// escape AH param separator
+					string tmp = text;
+					while(NLMISC::strFindReplace(tmp, "|", "&#124;"))
+						;
+					param = param + "|submit_button_value=" + tmp;
+				}
+
+				// Add the ctrl button
+				if (!_Paragraph)
+				{
+					newParagraph (0);
+					paragraphChange ();
+				}
+
+				typedef pair<string, string> TTmplParam;
+				vector<TTmplParam> tmplParams;
+				tmplParams.push_back(TTmplParam("id", name));
+				tmplParams.push_back(TTmplParam("onclick", "html_submit_form"));
+				tmplParams.push_back(TTmplParam("onclick_param", param));
+				//tmplParams.push_back(TTmplParam("text", text));
+				tmplParams.push_back(TTmplParam("active", "true"));
+				if (!minWidth.empty())
+					tmplParams.push_back(TTmplParam("wmin", minWidth));
+				CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
+				if (buttonGroup)
+				{
+
+					// Add the ctrl button
+					CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button"));
+					if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
+					if (ctrlButton)
+					{
+						ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
+
+						// Translate the tooltip
+						if (tooltip)
+						{
+							if (CI18N::hasTranslation(tooltip))
+							{
+								ctrlButton->setDefaultContextHelp(CI18N::get(tooltip));
+							}
+							else
+							{
+								ctrlButton->setDefaultContextHelp(ucstring(tooltip));
+							}
+						}
+
+						ctrlButton->setText(ucstring::makeFromUtf8(text));
+
+						setTextButtonStyle(ctrlButton, _Style.Current);
+					}
+					getParagraph()->addChild (buttonGroup);
+					paragraphChange ();
+				}
+			}
+			else if (type == "text")
+			{
+				// Get the string name
+				string name = elm.getAttribute("name");
+				ucstring ucValue;
+				ucValue.fromUtf8(elm.getAttribute("value"));
+
+				uint size = 120;
+				uint maxlength = 1024;
+				if (elm.hasNonEmptyAttribute("size"))
+					fromString(elm.getAttribute("size"), size);
+				if (elm.hasNonEmptyAttribute("maxlength"))
+					fromString(elm.getAttribute("maxlength"), maxlength);
+
+				string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup);
+				// Add the editbox
+				CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue, maxlength);
+				if (textArea)
+				{
+					// Add the text area to the form
+					CGroupHTML::CForm::CEntry entry;
+					entry.Name = name;
+					entry.TextArea = textArea;
+					_Forms.back().Entries.push_back (entry);
+				}
+			}
+			else if (type == "checkbox" || type == "radio")
+			{
+				renderPseudoElement(":before", elm);
+
+				CCtrlButton::EType btnType;
+				string name = elm.getAttribute("name");
+				string normal = elm.getAttribute("src");
+				string pushed;
+				string over;
+				ucstring ucValue = ucstring("on");
+				bool checked = elm.hasAttribute("checked");
+
+				// TODO: unknown if empty attribute should override or not
+				if (elm.hasNonEmptyAttribute("value"))
+					ucValue.fromUtf8(elm.getAttribute("value"));
+
+				if (type == "radio")
+				{
+					btnType = CCtrlButton::RadioButton;
+					normal = DefaultRadioButtonBitmapNormal;
+					pushed = DefaultRadioButtonBitmapPushed;
+					over = DefaultRadioButtonBitmapOver;
+				}
+				else
+				{
+					btnType = CCtrlButton::ToggleButton;
+					normal = DefaultCheckBoxBitmapNormal;
+					pushed = DefaultCheckBoxBitmapPushed;
+					over = DefaultCheckBoxBitmapOver;
+				}
+
+				// Add the ctrl button
+				CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style.Current);
+				if (checkbox)
+				{
+					if (btnType == CCtrlButton::RadioButton)
+					{
+						// override with 'id' because radio buttons share same name
+						if (!id.empty())
+							checkbox->setId(id);
+
+						// group together buttons with same name
+						CForm &form = _Forms.back();
+						bool notfound = true;
+						for (uint i=0; i<form.Entries.size(); i++)
+						{
+							if (form.Entries[i].Name == name && form.Entries[i].Checkbox->getType() == CCtrlButton::RadioButton)
+							{
+								checkbox->initRBRefFromRadioButton(form.Entries[i].Checkbox);
+								notfound = false;
+								break;
+							}
+						}
+						if (notfound)
+						{
+							// this will start a new group (initRBRef() would take first button in group container otherwise)
+							checkbox->initRBRefFromRadioButton(checkbox);
+						}
+					}
+
+					checkbox->setPushed (checked);
+
+					// Add the button to the form
+					CGroupHTML::CForm::CEntry entry;
+					entry.Name = name;
+					entry.Value = decodeHTMLEntities(ucValue);
+					entry.Checkbox = checkbox;
+					_Forms.back().Entries.push_back (entry);
+				}
+				renderPseudoElement(":after", elm);
+			}
+			else if (type == "hidden")
+			{
+				if (elm.hasNonEmptyAttribute("name"))
+				{
+					// Get the name
+					string name = elm.getAttribute("name");
+
+					// Get the value
+					ucstring ucValue;
+					ucValue.fromUtf8(elm.getAttribute("value"));
+
+					// Add an entry
+					CGroupHTML::CForm::CEntry entry;
+					entry.Name = name;
+					entry.Value = decodeHTMLEntities(ucValue);
+					_Forms.back().Entries.push_back (entry);
+				}
+			}
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlLI(const CHtmlElement &elm)
+	{
+		if (_UL.empty())
+			return;
+
+		// UL, OL top margin if this is the first LI
+		if (!_LI)
+		{
+			_LI = true;
+			newParagraph(ULBeginSpace);
+		}
+		else
+		{
+			newParagraph(LIBeginSpace);
+		}
+
+		// OL list index can be overridden by <li value="1"> attribute
+		if (elm.hasNonEmptyAttribute("value"))
+			fromString(elm.getAttribute("value"), _UL.back().Value);
+
+		ucstring str;
+		str.fromUtf8(_UL.back().getListMarkerText());
+		addString (str);
+
+		// list-style-type: outside
+		if (_CurrentViewLink)
+		{
+			getParagraph()->setFirstViewIndent(-_CurrentViewLink->getMaxUsedW());
+		}
+
+		flushString ();
+
+		// after marker
+		renderPseudoElement(":before", elm);
+
+		_UL.back().Value++;
+	}
+
+	void CGroupHTML::htmlLIend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlLUA(const CHtmlElement &elm)
+	{
+		// we receive an embeded lua script
+		_ParsingLua = _TrustedDomain; // Only parse lua if TrustedDomain
+		_LuaScript.clear();
+	}
+	
+	void CGroupHTML::htmlLUAend(const CHtmlElement &elm)
+	{
+		if (_ParsingLua && _TrustedDomain)
+		{
+			_ParsingLua = false;
+			// execute the embeded lua script
+			_LuaScript = "\nlocal __CURRENT_WINDOW__=\""+this->_Id+"\" \n"+_LuaScript;
+			CLuaManager::getInstance().executeLuaScript(_LuaScript, true);
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlMETA(const CHtmlElement &elm)
+	{
+		if (!_ReadingHeadTag)
+			return;
+
+		std::string httpEquiv = elm.getAttribute("http-equiv");
+		std::string httpContent = elm.getAttribute("content");
+		if (!httpEquiv.empty() && !httpContent.empty())
+		{
+			// only first http-equiv="refresh" should be handled
+			if (_RefreshUrl.empty() && httpEquiv == "refresh")
+			{
+				const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
+				double timeSec = times.thisFrameMs / 1000.0f;
+
+				string::size_type pos = httpContent.find_first_of(";");
+				if (pos == string::npos)
+				{
+					fromString(httpContent, _NextRefreshTime);
+					_RefreshUrl = _URL;
+				}
+				else
+				{
+					fromString(httpContent.substr(0, pos), _NextRefreshTime);
+
+					pos = toLower(httpContent).find("url=");
+					if (pos != string::npos)
+						_RefreshUrl = getAbsoluteUrl(httpContent.substr(pos + 4));
+				}
+
+				_NextRefreshTime += timeSec;
+			}
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlOBJECT(const CHtmlElement &elm)
+	{
+		_ObjectType = elm.getAttribute("type");
+		_ObjectData = elm.getAttribute("data");
+		_ObjectMD5Sum = elm.getAttribute("id");
+		_ObjectAction = elm.getAttribute("standby");
+		_Object = true;
+	}
+
+	void CGroupHTML::htmlOBJECTend(const CHtmlElement &elm)
+	{
+		if (!_TrustedDomain)
+			return;
+
+		if (_ObjectType=="application/ryzom-data")
+		{
+			if (!_ObjectData.empty())
+			{
+				if (addBnpDownload(_ObjectData, _ObjectAction, _ObjectScript, _ObjectMD5Sum))
+				{
+					CLuaManager::getInstance().executeLuaScript("\nlocal __ALLREADYDL__=true\n"+_ObjectScript, true);
+				}
+				_ObjectScript.clear();
+			}
+		}
+		_Object = false;
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlOL(const CHtmlElement &elm)
+	{
+		sint32 start = 1;
+		std::string type("1");
+
+		if (elm.hasNonEmptyAttribute("start"))
+			fromString(elm.getAttribute("start"), start);
+		if (elm.hasNonEmptyAttribute("type"))
+			type = elm.getAttribute("type");
+
+		_UL.push_back(HTMLOListElement(start, type));
+		// if LI is already present
+		_LI = _UL.size() > 1 || _DL.size() > 1;
+		_Indent.push_back(getIndent() + ULIndent);
+		endParagraph();
+
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlOLend(const CHtmlElement &elm)
+	{
+		htmlULend(elm);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlOPTION(const CHtmlElement &elm)
+	{
+		_SelectOption = true;
+		_SelectOptionStr.clear();
+
+		// Got one form ?
+		if (_Forms.empty() || _Forms.back().Entries.empty())
+			return;
+
+		_Forms.back().Entries.back().SelectValues.push_back(elm.getAttribute("value"));
+
+		if (elm.hasAttribute("selected"))
+			_Forms.back().Entries.back().InitialSelection = (sint)_Forms.back().Entries.back().SelectValues.size() - 1;
+
+		if (elm.hasAttribute("disabled"))
+			_Forms.back().Entries.back().sbOptionDisabled = (sint)_Forms.back().Entries.back().SelectValues.size() - 1;
+	}
+
+	void CGroupHTML::htmlOPTIONend(const CHtmlElement &elm)
+	{
+		if (_Forms.empty() || _Forms.back().Entries.empty())
+			return;
+
+		// insert the parsed text into the select control
+		CDBGroupComboBox *cb = _Forms.back().Entries.back().ComboBox;
+		if (cb)
+		{
+			uint lineIndex = cb->getNumTexts();
+			cb->addText(_SelectOptionStr);
+			if (_Forms.back().Entries.back().sbOptionDisabled == lineIndex)
+			{
+				cb->setGrayed(lineIndex, true);
+			}
+		}
+		else
+		{
+			CGroupMenu *sb = _Forms.back().Entries.back().SelectBox;
+			if (sb)
+			{
+				uint lineIndex = sb->getNumLine();
+				sb->addLine(_SelectOptionStr, "", "");
+
+				if (_Forms.back().Entries.back().sbOptionDisabled == lineIndex)
+				{
+					sb->setGrayedLine(lineIndex, true);
+				}
+				else
+				{
+					// create option line checkbox, CGroupMenu is taking ownership of the checbox
+					CInterfaceGroup *ig = CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_checkbox", "", NULL, 0);
+					if (ig)
+					{
+						CCtrlButton *cb = dynamic_cast<CCtrlButton *>(ig->getCtrl("b"));
+						if (cb)
+						{
+							if (_Forms.back().Entries.back().sbMultiple)
+							{
+								cb->setType(CCtrlButton::ToggleButton);
+								cb->setTexture(DefaultCheckBoxBitmapNormal);
+								cb->setTexturePushed(DefaultCheckBoxBitmapPushed);
+								cb->setTextureOver(DefaultCheckBoxBitmapOver);
+							}
+							else
+							{
+								cb->setType(CCtrlButton::RadioButton);
+								cb->setTexture(DefaultRadioButtonBitmapNormal);
+								cb->setTexturePushed(DefaultRadioButtonBitmapPushed);
+								cb->setTextureOver(DefaultRadioButtonBitmapOver);
+
+								if (_Forms.back().Entries.back().sbRBRef == NULL)
+									_Forms.back().Entries.back().sbRBRef = cb;
+
+								cb->initRBRefFromRadioButton(_Forms.back().Entries.back().sbRBRef);
+							}
+
+							cb->setPushed(_Forms.back().Entries.back().InitialSelection == lineIndex);
+							sb->setUserGroupLeft(lineIndex, ig);
+						}
+						else
+						{
+							nlwarning("Failed to get 'b' element from 'menu_checkbox' template");
+							delete ig;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlP(const CHtmlElement &elm)
+	{
+		newParagraph(PBeginSpace);
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlPend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+		endParagraph();
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlPRE(const CHtmlElement &elm)
+	{
+		_PRE.push_back(true);
+		newParagraph(0);
+
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlPREend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+
+		endParagraph();
+		popIfNotEmpty(_PRE);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlSCRIPT(const CHtmlElement &elm)
+	{
+		_IgnoreText = true;
+	}
+
+	void CGroupHTML::htmlSCRIPTend(const CHtmlElement &elm)
+	{
+		_IgnoreText = false;
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlSELECT(const CHtmlElement &elm)
+	{
+		if (_Forms.empty())
+			return;
+
+		// A select box
+		string name = elm.getAttribute("name");
+		bool multiple = elm.hasAttribute("multiple");
+		sint32 size = 0;
+
+		if (elm.hasNonEmptyAttribute("size"))
+			fromString(elm.getAttribute("size"), size);
+
+		CGroupHTML::CForm::CEntry entry;
+		entry.Name = name;
+		entry.sbMultiple = multiple;
+		if (size > 1 || multiple)
+		{
+			entry.InitialSelection = -1;
+			CGroupMenu *sb = addSelectBox(DefaultFormSelectBoxMenuGroup, name.c_str());
+			if (sb)
+			{
+				if (size < 1)
+					size = 4;
+
+				if (_Style.Current.Width > -1)
+					sb->setMinW(_Style.Current.Width);
+
+				if (_Style.Current.Height > -1)
+					sb->setMinH(_Style.Current.Height);
+
+				sb->setMaxVisibleLine(size);
+				sb->setFontSize(_Style.Current.FontSize);
+			}
+
+			entry.SelectBox = sb;
+		}
+		else
+		{
+			CDBGroupComboBox *cb = addComboBox(DefaultFormSelectGroup, name.c_str());
+			entry.ComboBox = cb;
+
+			if (cb)
+			{
+				// create view text
+				cb->updateCoords();
+				setTextStyle(cb->getViewText(), _Style.Current);
+			}
+		}
+		_Forms.back().Entries.push_back (entry);
+	}
+
+	void CGroupHTML::htmlSELECTend(const CHtmlElement &elm)
+	{
+		_SelectOption = false;
+		if (_Forms.empty() || _Forms.back().Entries.empty())
+			return;
+
+		CDBGroupComboBox *cb = _Forms.back().Entries.back().ComboBox;
+		if (cb)
+		{
+			cb->setSelectionNoTrigger(_Forms.back().Entries.back().InitialSelection);
+			// TODO: magic padding
+			cb->setW(cb->evalContentWidth() + 16);
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlSTYLE(const CHtmlElement &elm)
+	{
+		_IgnoreText = true;
+	}
+
+	void CGroupHTML::htmlSTYLEend(const CHtmlElement &elm)
+	{
+		_IgnoreText = false;
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlTABLE(const CHtmlElement &elm)
+	{
+		// Get cells parameters
+		getCellsParameters(elm, false);
+
+		CGroupTable *table = new CGroupTable(TCtorParam());
+		table->BgColor = _CellParams.back().BgColor;
+
+		// TODO: border-spacing: 2em;
+		{
+			if (elm.hasNonEmptyAttribute("cellspacing"))
+				fromString(elm.getAttribute("cellspacing"), table->CellSpacing);
+			
+			// TODO: cssLength, horiz/vert values
+			if (_Style.hasStyle("border-spacing"))
+				fromString(_Style.getStyle("border-spacing"), table->CellSpacing);
+
+			// overrides border-spacing if set to 'collapse'
+			if (_Style.checkStyle("border-collapse", "collapse"))
+				table->CellSpacing = 0;
+		}
+
+		if (elm.hasNonEmptyAttribute("cellpadding"))
+			fromString(elm.getAttribute("cellpadding"), table->CellPadding);
+
+		if (_Style.hasStyle("width"))
+			getPercentage(table->ForceWidthMin, table->TableRatio, _Style.getStyle("width").c_str());
+		else if (elm.hasNonEmptyAttribute("width"))
+			getPercentage (table->ForceWidthMin, table->TableRatio, elm.getAttribute("width").c_str());
+
+		if (_Style.hasStyle("border") || _Style.hasStyle("border-width"))
+		{
+			table->Border = _Style.Current.BorderWidth;
+		}
+		else if (elm.hasAttribute("border"))
+		{
+			std::string s = elm.getAttribute("border");
+			if (s.empty())
+				table->Border = 1;
+			else
+				fromString(elm.getAttribute("border"), table->Border);
+		}
+
+		if (_Style.hasStyle("border-color"))
+		{
+			std::string s = toLower(_Style.getStyle("border-color"));
+			if (s == "currentcolor")
+				table->BorderColor = _Style.Current.TextColor;
+			else
+				scanHTMLColor(s.c_str(), table->BorderColor);
+		}
+		else if (elm.hasNonEmptyAttribute("bordercolor"))
+		{
+			scanHTMLColor(elm.getAttribute("bordercolor").c_str(), table->BorderColor);
+		}
+
+		table->setMarginLeft(getIndent());
+		addHtmlGroup (table, 0);
+
+		renderPseudoElement(":before", elm);
+
+		_Tables.push_back(table);
+
+		// Add a cell pointer
+		_Cells.push_back(NULL);
+		_TR.push_back(false);
+		_Indent.push_back(0);
+	}
+
+	void CGroupHTML::htmlTABLEend(const CHtmlElement &elm)
+	{
+		popIfNotEmpty(_CellParams);
+		popIfNotEmpty(_TR);
+		popIfNotEmpty(_Cells);
+		popIfNotEmpty(_Tables);
+		popIfNotEmpty(_Indent);
+
+		renderPseudoElement(":after", elm);
+		endParagraph();
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlTD(const CHtmlElement &elm)
+	{
+		// Get cells parameters
+		getCellsParameters(elm, true);
+
+		if (elm.ID == HTML_TH)
+		{
+			if (!_Style.hasStyle("font-weight"))
+				_Style.Current.FontWeight = FONT_WEIGHT_BOLD;
+			// center if not specified otherwise.
+			if (!elm.hasNonEmptyAttribute("align") && !_Style.hasStyle("text-align"))
+				_CellParams.back().Align = CGroupCell::Center;
+		}
+
+		CGroupTable *table = getTable();
+		if (table)
+		{
+			if (_Style.hasStyle("padding"))
+			{
+				uint32 a;
+				// TODO: cssLength
+				if (fromString(_Style.getStyle("padding"), a))
+					table->CellPadding = a;
+			}
+
+			if (!_Cells.empty())
+			{
+				_Cells.back() = new CGroupCell(CViewBase::TCtorParam());
+
+				if (_Style.checkStyle("background-repeat", "1") || _Style.checkStyle("background-repeat", "repeat"))
+					_Cells.back()->setTextureTile(true);
+
+				if (_Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "cover"))
+					_Cells.back()->setTextureScale(true);
+
+				if (_Style.hasStyle("background-image"))
+				{
+					string image = _Style.getStyle("background-image");
+
+					string::size_type texExt = toLower(image).find("url(");
+					// Url image
+					if (texExt != string::npos)
+					{
+						// Remove url()
+						image = image.substr(4, image.size()-5);
+						addImageDownload(image, _Cells.back());
+					// Image in BNP
+					}
+					else
+					{
+						_Cells.back()->setTexture(image);
+					}
+				}
+
+				if (elm.hasNonEmptyAttribute("colspan"))
+					fromString(elm.getAttribute("colspan"), _Cells.back()->ColSpan);
+				if (elm.hasNonEmptyAttribute("rowspan"))
+					fromString(elm.getAttribute("rowspan"), _Cells.back()->RowSpan);
+
+				_Cells.back()->BgColor = _CellParams.back().BgColor;
+				_Cells.back()->Align = _CellParams.back().Align;
+				_Cells.back()->VAlign = _CellParams.back().VAlign;
+				_Cells.back()->LeftMargin = _CellParams.back().LeftMargin;
+				_Cells.back()->NoWrap = _CellParams.back().NoWrap;
+				_Cells.back()->ColSpan = std::max(1, _Cells.back()->ColSpan);
+				_Cells.back()->RowSpan = std::max(1, _Cells.back()->RowSpan);
+
+				float temp;
+				if (_Style.hasStyle("width"))
+					getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, _Style.getStyle("width").c_str());
+				else if (elm.hasNonEmptyAttribute("width"))
+					getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, elm.getAttribute("width").c_str());
+				
+				if (_Style.hasStyle("height"))
+					getPercentage (_Cells.back()->Height, temp, _Style.getStyle("height").c_str());
+				else if (elm.hasNonEmptyAttribute("height"))
+					getPercentage (_Cells.back()->Height, temp, elm.getAttribute("height").c_str());
+
+				_Cells.back()->NewLine = getTR();
+				table->addChild (_Cells.back());
+
+				// reusing indent pushed by table
+				_Indent.back() = 0;
+
+				newParagraph(TDBeginSpace);
+				// indent is already 0, getParagraph()->setMarginLeft(0); // maybe setIndent(0) if LI is using one
+
+				// Reset TR flag
+				if (!_TR.empty())
+					_TR.back() = false;
+
+				renderPseudoElement(":before", elm);
+			}
+		}
+	}
+
+	void CGroupHTML::htmlTDend(const CHtmlElement &elm)
+	{
+		renderPseudoElement(":after", elm);
+
+		popIfNotEmpty(_CellParams);
+		if (!_Cells.empty())
+			_Cells.back() = NULL;
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlTEXTAREA(const CHtmlElement &elm)
+	{
+		_PRE.push_back(true);
+
+		// Got one form ?
+		if (!(_Forms.empty()))
+		{
+			// read general property
+			string templateName;
+
+			// Widget template name
+			if (elm.hasNonEmptyAttribute("z_input_tmpl"))
+				templateName = elm.getAttribute("z_input_tmpl");
+
+			// Get the string name
+			_TextAreaName.clear();
+			_TextAreaRow = 1;
+			_TextAreaCols = 10;
+			_TextAreaContent.clear();
+			_TextAreaMaxLength = 1024;
+			if (elm.hasNonEmptyAttribute("name"))
+				_TextAreaName = elm.getAttribute("name");
+			if (elm.hasNonEmptyAttribute("rows"))
+				fromString(elm.getAttribute("rows"), _TextAreaRow);
+			if (elm.hasNonEmptyAttribute("cols"))
+				fromString(elm.getAttribute("cols"), _TextAreaCols);
+			if (elm.hasNonEmptyAttribute("maxlength"))
+				fromString(elm.getAttribute("maxlength"), _TextAreaMaxLength);
+
+			_TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup;
+			_TextArea = true;
+		}
+	}
+
+	void CGroupHTML::htmlTEXTAREAend(const CHtmlElement &elm)
+	{
+		_TextArea = false;
+		popIfNotEmpty (_PRE);
+
+		if (_Forms.empty())
+			return;
+
+		CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength);
+		if (textArea)
+		{
+			// Add the text area to the form
+			CGroupHTML::CForm::CEntry entry;
+			entry.Name = _TextAreaName;
+			entry.TextArea = textArea;
+			_Forms.back().Entries.push_back (entry);
+		}
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlTH(const CHtmlElement &elm)
+	{
+		htmlTD(elm);
+	}
+
+	void CGroupHTML::htmlTHend(const CHtmlElement &elm)
+	{
+		htmlTDend(elm);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlTITLE(const CHtmlElement &elm)
+	{
+		// TODO: only from <head>
+		// if (!_ReadingHeadTag) return;
+		if(!_TitlePrefix.empty())
+			_TitleString = _TitlePrefix + " - ";
+		else
+			_TitleString.clear();
+		_Title = true;
+	}
+
+	void CGroupHTML::htmlTITLEend(const CHtmlElement &elm)
+	{
+		_Title = false;
+		setTitle(_TitleString);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlTR(const CHtmlElement &elm)
+	{
+		// Get cells parameters
+		getCellsParameters(elm, true);
+
+		// TODO: this probably ends up in first cell
+		renderPseudoElement(":before", elm);
+
+		// Set TR flag
+		if (!_TR.empty())
+			_TR.back() = true;
+	}
+
+	void CGroupHTML::htmlTRend(const CHtmlElement &elm)
+	{
+		// TODO: this probably ends up in last cell
+		renderPseudoElement(":after", elm);
+
+		popIfNotEmpty(_CellParams);
+	}
+
+	// ***************************************************************************
+	void CGroupHTML::htmlUL(const CHtmlElement &elm)
+	{
+		if (_UL.empty())
+			_UL.push_back(HTMLOListElement(1, "disc"));
+		else if (_UL.size() == 1)
+			_UL.push_back(HTMLOListElement(1, "circle"));
+		else
+			_UL.push_back(HTMLOListElement(1, "square"));
+
+		// if LI is already present
+		_LI = _UL.size() > 1 || _DL.size() > 1;
+		_Indent.push_back(getIndent() + ULIndent);
+		endParagraph();
+
+		renderPseudoElement(":before", elm);
+	}
+
+	void CGroupHTML::htmlULend(const CHtmlElement &elm)
+	{
+		if (_UL.empty())
+			return;
+
+		renderPseudoElement(":after", elm);
+
+		endParagraph();
+		popIfNotEmpty(_UL);
+		popIfNotEmpty(_Indent);
+	}
+
 }
 
diff --git a/code/nel/src/gui/html_element.cpp b/code/nel/src/gui/html_element.cpp
new file mode 100644
index 000000000..215c1c9f5
--- /dev/null
+++ b/code/nel/src/gui/html_element.cpp
@@ -0,0 +1,168 @@
+// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "stdpch.h"
+
+#include "nel/gui/html_element.h"
+
+using namespace std;
+using namespace NLMISC;
+
+#ifdef DEBUG_NEW
+#define new DEBUG_NEW
+#endif
+
+namespace NLGUI
+{
+	// ***************************************************************************
+	CHtmlElement::CHtmlElement(ENodeType type, std::string value)
+		: ID(0), Type(type), Value(value), parent(NULL), previousSibling(NULL), nextSibling(NULL), childIndex(0)
+	{}
+
+	// ***************************************************************************
+	bool CHtmlElement::hasAttribute(const std::string &key) const
+	{
+		return Attributes.find(key) != Attributes.end();
+	}
+
+	// ***************************************************************************
+	bool CHtmlElement::hasNonEmptyAttribute(const std::string &key) const
+	{
+		return !getAttribute(key).empty();
+	}
+
+	// ***************************************************************************
+	std::string CHtmlElement::getAttribute(const std::string &key) const
+	{
+		std::map<std::string, std::string>::const_iterator it = Attributes.find(key);
+		return (it != Attributes.end() ? it->second : "");
+	}
+
+	// ***************************************************************************
+	bool CHtmlElement::hasClass(const std::string &key) const
+	{
+		return ClassNames.find(key) != ClassNames.end();
+	}
+
+	// ***************************************************************************
+	void CHtmlElement::reindexChilds()
+	{
+		uint index = 0;
+		CHtmlElement *prev = NULL;
+		std::list<CHtmlElement>::iterator it;
+		for(it = Children.begin(); it != Children.end(); ++it)
+		{
+			if (it->Type == ELEMENT_NODE)
+			{
+				it->parent = this;
+				it->previousSibling = prev;
+				it->nextSibling = NULL;
+				if (prev)
+				{
+					prev->nextSibling = &(*it);
+				}
+				it->childIndex = index;
+				index++;
+				prev = &(*it);
+			}
+		}
+	}
+
+	// ***************************************************************************
+	std::string CHtmlElement::toString(bool tree, uint depth) const
+	{
+		std::string result;
+		if (depth > 0)
+		{
+			result = NLMISC::toString("[%d]", depth);
+			result.append(depth, '-');
+		}
+		if (Type == NONE || Type == ELEMENT_NODE)
+		{
+			result += "<" + Value;
+			for(std::map<std::string, std::string>::const_iterator it = Attributes.begin(); it != Attributes.end(); ++it)
+			{
+				if (it->first == "class")
+				{
+					result += " class=\"";
+					for(std::set<std::string>::const_iterator it2 = ClassNames.begin(); it2 != ClassNames.end(); ++it2)
+					{
+						if (it2 != ClassNames.begin())
+						{
+							result += " ";
+						}
+						result += *it2;
+					}
+					result += "\"";
+				}
+				else
+				{
+					result += " " + it->first + "=\"" + it->second + "\"";
+				}
+			}
+			result += NLMISC::toString(" data-debug=\"childIndex: %d\"", childIndex);
+			result += ">";
+
+			if (tree)
+			{
+				result += "\n";
+				for(std::list<CHtmlElement>::const_iterator it = Children.begin(); it != Children.end(); ++it)
+				{
+					result += it->toString(tree, depth+1);
+				}
+				if (depth > 0)
+				{
+					result += NLMISC::toString("[%d]", depth);
+					result.append(depth, '-');
+				}
+				result += "</" + Value + ">\n";
+			}
+		}
+		else
+		{
+			if (Value.find("\n") == std::string::npos)
+			{
+				result += "{" + Value + "}";
+			}
+			else
+			{
+				result += "{";
+				std::string::size_type start = 0;
+				std::string::size_type pos = Value.find_first_of("\n\r\t");
+				while(pos != std::string::npos)
+				{
+					result += Value.substr(start, pos - start);
+					if (Value[pos] == '\n')
+					{
+						result += "⏎";
+					}
+					else if (Value[pos] == '\t')
+					{
+						result += "⇥";
+					}
+
+					start = pos+1;
+					pos = Value.find_first_of("\n\r\t", start);
+				}
+				result += "}";
+			}
+			if (tree) result += "\n";
+		}
+
+		return result;
+	};
+} // namespace
diff --git a/code/nel/src/gui/html_parser.cpp b/code/nel/src/gui/html_parser.cpp
index 8470d0524..d411b856e 100644
--- a/code/nel/src/gui/html_parser.cpp
+++ b/code/nel/src/gui/html_parser.cpp
@@ -35,71 +35,40 @@ using namespace NLMISC;
 
 namespace NLGUI
 {
+
 	// ***************************************************************************
-	void CHtmlParser::htmlElement(xmlNode *node, int element_number)
+	void CHtmlParser::parseStyle(xmlNode *a_node, std::string &styleString) const
 	{
-		SGML_dtd *HTML_DTD = HTML_dtd ();
-
-		if (element_number < HTML_ELEMENTS)
+		xmlNode *node = a_node;
+		while(node)
 		{
-			CXMLAutoPtr ptr;
-			// load attributes into libwww structs
-			std::vector<bool> present;
-			std::vector<const char *>value;
-			std::string strvalues[MAX_ATTRIBUTES];
-			present.resize(30, false);
-			value.resize(30);
-
-			uint nbAttributes = std::min(MAX_ATTRIBUTES, HTML_DTD->tags[element_number].number_of_attributes);
-			for(uint i=0; i<nbAttributes; i++)
+			if (node->type == XML_CDATA_SECTION_NODE)
 			{
-				std::string name;
-				name = toLower(std::string(HTML_DTD->tags[element_number].attributes[i].name));
-				ptr = xmlGetProp(node, (const xmlChar *)name.c_str());
-				if (ptr)
-				{
-					// copy xmlChar to string (xmlChar will be released)
-					strvalues[i] = (const char *)(ptr);
-					// now use string pointer in value[] array
-					value[i] = strvalues[i].c_str();
-					present[i] = true;
-				}
+				styleString += (const char*)node->content;
+			}
+			else
+			{
+				nlwarning("<style> tag has child elements other than cdata[%d]", node->type);
 			}
 
-			_GroupHtml->beginElement(element_number, present, value);
-		}
-		else
-		{
-			_GroupHtml->beginUnparsedElement((const char *)(node->name), xmlStrlen(node->name));
-		}
-
-		// recursive - text content / child nodes
-		parseNode(node->children);
-
-		// closing tag
-		if (element_number < HTML_ELEMENTS)
-		{
-			_GroupHtml->endElement(element_number);
-		}
-		else
-		{
-			_GroupHtml->endUnparsedElement((const char *)(node->name), xmlStrlen(node->name));
+			node = node->next;
 		}
 	}
 
 	// ***************************************************************************
 	// recursive function to walk html document
-	void CHtmlParser::parseNode(xmlNode *a_node)
+	void CHtmlParser::parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const
 	{
 		SGML_dtd *HTML_DTD = HTML_dtd ();
 
+		uint childIndex = 0;
 		uint element_number;
 		xmlNode *node = a_node;
 		while(node)
 		{
 			if (node->type == XML_TEXT_NODE)
 			{
-				_GroupHtml->addText((const char *)(node->content), xmlStrlen(node->content));
+				parent.Children.push_back(CHtmlElement(CHtmlElement::TEXT_NODE, (const char*)(node->content)));
 			}
 			else
 			if (node->type == XML_ELEMENT_NODE)
@@ -111,7 +80,123 @@ namespace NLGUI
 						break;
 				}
 
-				htmlElement(node, element_number);
+				// get pointer to previous sibling
+				CHtmlElement *prevSibling = NULL;
+				if (!parent.Children.empty())
+				{
+					// skip text nodes
+					for(std::list<CHtmlElement>::reverse_iterator it = parent.Children.rbegin(); it != parent.Children.rend(); ++it)
+					{
+						if (it->Type == CHtmlElement::ELEMENT_NODE)
+						{
+							prevSibling = &(*it);
+							break;
+						}
+					}
+				}
+
+				parent.Children.push_back(CHtmlElement(CHtmlElement::ELEMENT_NODE, toLower((const char*)node->name)));
+				CHtmlElement &elm = parent.Children.back();
+				elm.ID = element_number;
+				elm.parent = &parent;
+				elm.childIndex = childIndex;
+
+				// previous/next sibling that is ELEMENT_NODE
+				elm.previousSibling = prevSibling;
+				if (prevSibling)
+				{
+					prevSibling->nextSibling = &parent.Children.back();
+				}
+
+				childIndex++;
+
+				// TODO: harvest <link type="css">, <style>, <img>
+
+				elm.Attributes.clear();
+
+				for (xmlAttr *cur_attr = node->properties; cur_attr; cur_attr = cur_attr->next) {
+					std::string key(toLower((const char *)(cur_attr->name)));
+					std::string value;
+					if (cur_attr->children)
+					{
+						value = (const char *)(cur_attr->children->content);
+					}
+					elm.Attributes[key] = value;
+				}
+
+				if (elm.hasAttribute("class"))
+				{
+					std::vector<std::string> parts;
+					NLMISC::splitString(elm.getAttribute("class"), " ", parts);
+					for(uint i = 0; i<parts.size();++i)
+					{
+						elm.ClassNames.insert(toLower(trim(parts[i])));
+					}
+				}
+
+				if (elm.Value == "style")
+				{
+					// <style type="text/css" media="all, screen">
+					// ...
+					// </style>
+					bool useStyle = true;
+					if (elm.hasAttribute("media"))
+					{
+						std::string media = trim(toLower(elm.Attributes["media"]));
+						useStyle = media.empty() || media.find("all") != std::string::npos || media.find("screen") != std::string::npos;
+
+						// <style media="ryzom"> for ingame browser
+						useStyle = useStyle || media == "ryzom";
+					}
+
+					if (useStyle)
+					{
+						parseStyle(node->children, styleString);
+					}
+					// style tag is kept in dom
+				}
+				if (elm.Value == "link" && elm.getAttribute("rel") == "stylesheet")
+				{
+					bool useStyle = true;
+					if (elm.hasAttribute("media"))
+					{
+						std::string media = trim(toLower(elm.Attributes["media"]));
+						useStyle = media.empty() || media.find("all") != std::string::npos || media.find("screen") != std::string::npos;
+
+						// <style media="ryzom"> for ingame browser
+						useStyle = useStyle || media == "ryzom";
+					}
+
+					if (useStyle)
+					{
+						links.push_back(elm.getAttribute("href"));
+					}
+					// link tag is kept in dom
+				}
+				else if (node->children)
+				{
+					parseNode(node->children, elm, styleString, links);
+
+					// must cleanup nested tags that libxml2 does not fix
+					// dt without end tag: <dl><dt><dt></dl>
+					// dd without end tag: <dl><dd><dd></dl>
+					if (!elm.Children.empty() && (elm.Value == "dt" || elm.Value == "dd"))
+					{
+						std::string tag = elm.Value;
+						std::list<CHtmlElement>::iterator it;
+						for(it = elm.Children.begin(); it != elm.Children.end(); ++it)
+						{
+							if (it->Type == CHtmlElement::ELEMENT_NODE && it->Value == tag)
+							{
+								// relocate this and remaining elements over to parent
+								parent.Children.splice(parent.Children.end(), elm.Children, it, elm.Children.end());
+								break;
+							}
+						}
+						elm.reindexChilds();
+						parent.reindexChilds();
+					}
+				}
 			}
 
 			// move into next sibling
@@ -298,13 +383,13 @@ namespace NLGUI
 	}
 
 	// ***************************************************************************
-	bool CHtmlParser::parseHtml(std::string htmlString)
+	void CHtmlParser::getDOM(std::string htmlString, CHtmlElement &dom, std::string &styleString, std::vector<std::string> &links) const
 	{
 		htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, XML_CHAR_ENCODING_UTF8);
 		if (!parser)
 		{
 			nlwarning("Creating html parser context failed");
-			return false;
+			return;
 		}
 
 		htmlCtxtUseOptions(parser, HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_NONET);
@@ -315,29 +400,26 @@ namespace NLGUI
 		htmlParseChunk(parser, htmlString.c_str(), htmlString.size(), 0);
 		htmlParseChunk(parser, "", 0, 1);
 
-		bool success = true;
 		if (parser->myDoc)
 		{
 			xmlNode *root = xmlDocGetRootElement(parser->myDoc);
 			if (root)
 			{
-				parseNode(root);
+				styleString.clear();
+				parseNode(root, dom, styleString, links);
 			}
 			else
 			{
 				nlwarning("html root node failed");
-				success = false;
 			}
 			xmlFreeDoc(parser->myDoc);
 		}
 		else
 		{
 			nlwarning("htmlstring parsing failed");
-			success = false;
 		}
 
 		htmlFreeParserCtxt(parser);
-		return success;
 	}
 
 }
diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp
index 50cac24bf..0ee6c01f2 100644
--- a/code/nel/src/gui/libwww.cpp
+++ b/code/nel/src/gui/libwww.cpp
@@ -599,6 +599,11 @@ namespace NLGUI
 			return true;
 		}
 
+		// TODO: CSS Colors Level 4 support
+		// Whitespace syntax, aliases: rgb == rgba, hsl == hsla
+		// rgb(51 170 51 / 0.4)    /* 40% opaque green */ 
+		// rgb(51 170 51 / 40%)    /* 40% opaque green */ 
+
 		if (strnicmp(src, "rgb(", 4) == 0 || strnicmp(src, "rgba(", 5) == 0)
 		{
 			src += 4;
@@ -743,6 +748,11 @@ namespace NLGUI
 		return dst;
 	}
 
+	std::string getRGBAString(const CRGBA &color)
+	{
+		return toString("rgba(%d, %d, %d, %.1f)", color.R, color.G, color.B, color.A / 255.f);
+	}
+
 	// update HTTPCookies list
 	static void receiveCookie(const char *nsformat, const std::string &domain, bool trusted)
 	{
diff --git a/code/nel/src/gui/libwww_types.cpp b/code/nel/src/gui/libwww_types.cpp
index 9731e9aca..12a16e5d6 100644
--- a/code/nel/src/gui/libwww_types.cpp
+++ b/code/nel/src/gui/libwww_types.cpp
@@ -784,6 +784,8 @@ static HTTag tags[HTML_ELEMENTS] = {
 	{ "U"	, gen_attr,	HTML_GEN_ATTRIBUTES },
 	{ "UL"	, ul_attr,	HTML_UL_ATTRIBUTES },
 	{ "VAR"	, gen_attr,	HTML_GEN_ATTRIBUTES },
+	//
+	{ "LUA" , gen_attr, HTML_GEN_ATTRIBUTES },
 };
 
 static SGML_dtd HTMLP_dtd = {
diff --git a/code/ryzom/client/src/interface_v3/group_quick_help.cpp b/code/ryzom/client/src/interface_v3/group_quick_help.cpp
index 144dc9b9a..857c3cacd 100644
--- a/code/ryzom/client/src/interface_v3/group_quick_help.cpp
+++ b/code/ryzom/client/src/interface_v3/group_quick_help.cpp
@@ -25,6 +25,7 @@
 #include "nel/gui/group_list.h"
 #include "nel/gui/group_paragraph.h"
 #include "nel/gui/libwww.h"
+#include "nel/gui/html_element.h"
 #include "interface_manager.h"
 #include "nel/gui/action_handler.h"
 #include "nel/misc/xml_auto_ptr.h"
@@ -215,33 +216,29 @@ void CGroupQuickHelp::setGroupTextSize (CInterfaceGroup *group, bool selected)
 
 extern CActionsContext ActionsContext;
 
-void CGroupQuickHelp::beginElement (uint element_number, const std::vector<bool> &present, const std::vector<const char *>&value)
+void CGroupQuickHelp::beginElement(CHtmlElement &elm)
 {
-	CGroupHTML::beginElement (element_number, present, value);
+	CGroupHTML::beginElement (elm);
 
 	// Paragraph ?
-	switch(element_number)
+	switch(elm.ID)
 	{
 	case HTML_A:
 			// Quick help
-			if (_TrustedDomain && present[MY_HTML_A_Z_ACTION_SHORTCUT] && value[MY_HTML_A_Z_ACTION_SHORTCUT])
+			if (_TrustedDomain && elm.hasNonEmptyAttribute("z_action_shortcut"))
 			{
 				// Get the action category
-				string category;
-				if (present[MY_HTML_A_Z_ACTION_CATEGORY] && value[MY_HTML_A_Z_ACTION_CATEGORY])
-					category = value[MY_HTML_A_Z_ACTION_CATEGORY];
+				string category = elm.getAttribute("z_action_category");
 
 				// Get the action params
-				string params;
-				if (present[MY_HTML_A_Z_ACTION_PARAMS] && value[MY_HTML_A_Z_ACTION_PARAMS])
-					params = value[MY_HTML_A_Z_ACTION_PARAMS];
+				string params = elm.getAttribute("z_action_params");
 
 				// Get the action descriptor
 				CActionsManager *actionManager = ActionsContext.getActionsManager (category);
 				if (actionManager)
 				{
 					const CActionsManager::TActionComboMap &actionCombo = actionManager->getActionComboMap ();
-					CActionsManager::TActionComboMap::const_iterator ite = actionCombo.find (CAction::CName (value[MY_HTML_A_Z_ACTION_SHORTCUT], params.c_str()));
+					CActionsManager::TActionComboMap::const_iterator ite = actionCombo.find (CAction::CName (elm.getAttribute("z_action_shortcut").c_str(), params.c_str()));
 					if (ite != actionCombo.end())
 					{
 						addString (ite->second.toUCString());
@@ -252,7 +249,7 @@ void CGroupQuickHelp::beginElement (uint element_number, const std::vector<bool>
 
 	case HTML_P:
 		// Get the action name
-		if (present[MY_HTML_P_QUICK_HELP_EVENTS])
+		if (elm.hasAttribute("quick_help_events"))
 		{
 			// This page is a quick help
 			_IsQuickHelp = true;
@@ -260,38 +257,29 @@ void CGroupQuickHelp::beginElement (uint element_number, const std::vector<bool>
 			_Steps.push_back (CStep());
 			CStep &step = _Steps.back();
 
-			if (value[MY_HTML_P_QUICK_HELP_EVENTS])
+			// Get the event names
+			string events = elm.getAttribute("quick_help_events");
+			if (!events.empty())
 			{
-				// Get the event names
-				string events = value[MY_HTML_P_QUICK_HELP_EVENTS];
-				if (!events.empty())
+				uint first = 0;
+				while (first < events.size())
 				{
-					uint first = 0;
-					while (first < events.size())
-					{
-						// String end
-						string::size_type last = events.find_first_of(" ", first);
-						if (last == string::npos)
-							last = events.size();
+					// String end
+					string::size_type last = events.find_first_of(" ", first);
+					if (last == string::npos)
+						last = events.size();
 
-						// Extract the string
-						step.EventToComplete.insert (events.substr (first, last-first));
-						first = (uint)last+1;
-					}
+					// Extract the string
+					step.EventToComplete.insert (events.substr (first, last-first));
+					first = (uint)last+1;
 				}
 			}
 
 			// Get the condition
-			if (present[MY_HTML_P_QUICK_HELP_CONDITION] && value[MY_HTML_P_QUICK_HELP_CONDITION])
-			{
-				step.Condition = value[MY_HTML_P_QUICK_HELP_CONDITION];
-			}
+			step.Condition = elm.getAttribute("quick_help_condition");
 
 			// Get the action handlers to run
-			if (present[MY_HTML_P_QUICK_HELP_LINK] && value[MY_HTML_P_QUICK_HELP_LINK])
-			{
-				step.URL = value[MY_HTML_P_QUICK_HELP_LINK];
-			}
+			step.URL = elm.getAttribute("quick_help_link");
 		}
 		break;
 	}
diff --git a/code/ryzom/client/src/interface_v3/group_quick_help.h b/code/ryzom/client/src/interface_v3/group_quick_help.h
index 3dc1c8afa..6af4e91b0 100644
--- a/code/ryzom/client/src/interface_v3/group_quick_help.h
+++ b/code/ryzom/client/src/interface_v3/group_quick_help.h
@@ -23,7 +23,6 @@
 #include "nel/misc/types_nl.h"
 #include "nel/gui/group_html.h"
 
-
 /**
  * Quick help group
  * \author Cyril 'Hulud' Corvazier
@@ -48,7 +47,7 @@ private:
 	virtual void updateCoords();
 
 	// From CGroupHTML
-	virtual void beginElement (uint element_number, const std::vector<bool> &present, const std::vector<const char *>&value);
+	virtual void beginElement (NLGUI::CHtmlElement &elm);
 	virtual void endBuild ();
 	virtual void browse (const char *url);
 	virtual std::string	home();

From 7e29fcc33d4577aa4ffe681a7e67bf433c9a9a9e Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Thu, 25 Apr 2019 01:25:20 +0800
Subject: [PATCH 09/75] Script to dump animation timings

---
 .../scripts/nel_assets_dump_timings.ms        | 263 ++++++++++++++++++
 1 file changed, 263 insertions(+)
 create mode 100644 code/nel/tools/3d/plugin_max/scripts/nel_assets_dump_timings.ms

diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_assets_dump_timings.ms b/code/nel/tools/3d/plugin_max/scripts/nel_assets_dump_timings.ms
new file mode 100644
index 000000000..2730ce345
--- /dev/null
+++ b/code/nel/tools/3d/plugin_max/scripts/nel_assets_dump_timings.ms
@@ -0,0 +1,263 @@
+
+NEL3D_APPDATA_INTERFACE_FILE = 1423062700
+
+-- Allocate 20 Me for the script
+heapSize += 30000000
+
+nlErrorFilename = "W:/database/timings.log"
+nlErrorStream = openFile nlErrorFilename mode:"w"
+if nlErrorStream == undefined then
+	nlErrorStream = createFile nlErrorFilename
+
+-- Log a message
+fn nllog message =
+(
+	if nlErrorStream != undefined then
+	(
+		format "%\n" message to:nlErrorStream
+		flush nlErrorStream
+	)
+
+	-- To the console
+	print message
+)
+
+include "nel_utility.ms"
+
+rollout assets_resave_rollout "Properties"
+(
+	fn do_it =
+	(
+		max select none
+		
+		actionMan.executeAction 0 "40021"  -- Selection: Select All
+		actionMan.executeAction 0 "311"  -- Tools: Zoom Extents All Selected
+		actionMan.executeAction 0 "40807"  -- Views: Activate All Maps
+		actionMan.executeAction 0 "63508"  -- Views: Standard Display with Maps
+		actionMan.executeAction 0 "40043"  -- Selection: Select None
+		
+		max views redraw
+		
+		return 1
+	)
+	
+	-- This script is a base script to include to add multiple functionality to your script
+
+	-- To use this script
+	--	Include it in your script into the rollout at the beginning.
+	--	Implement a do_it function to do the job in your rollout.
+	--	The function should retun -1 if an arror occurred, else the count of modification done
+	--	It the function returns <1, the project will not be overwritten
+
+	Group "Running properties"
+	(
+		RadioButtons	SourceFiles				"Source projects"				labels:#("Current project", "All Projects in a folder") align:#left
+
+		Label			DirectoryLabel			"Source directory"							align:#left
+		EditText		Directory				""								width:500	align:#left enabled:false
+		Button			BrowseDirectory			"Browse..."						align:#left enabled:false
+
+		CheckBox		Recurse					"Look in subfolders"			checked:true enabled:false
+		CheckBox		Test					"Test only, do not save"		checked:false enabled:false
+		CheckBox		BackupFiles				"Backup files"					checked:false enabled:false
+		CheckBox		StopOnError				"Stop on error"					checked:false enabled:false
+		CheckBox		UseTag					"Use tag"						checked:false enabled:false
+
+		Label			ProgressText											width:500	align:#left
+		ProgressBar		Progress												width:500	align:#left
+
+		Button 			GoButton				"Go"							width:500	align:#left
+	)
+	
+	local countModifications
+	local countErrors
+	local fileModified
+	local fileParsed
+
+	fn UpdateData =
+	(
+		if SourceFiles.state == 2 then
+			isSourceDir = true
+		else
+			isSourceDir = false
+		if Test.checked == true then
+			isTest = true
+		else
+			isTest = false
+
+		Directory.enabled = isSourceDir
+		BrowseDirectory.enabled = isSourceDir
+		Recurse.enabled = isSourceDir
+		Test.enabled = isSourceDir
+		BackupFiles.enabled = isSourceDir and (isTest == false)
+		StopOnError.enabled = isSourceDir
+		UseTag.enabled = isSourceDir
+	)
+
+	on SourceFiles changed state do
+	(
+		UpdateData ()
+	)
+
+	on Test changed state do
+	(
+		UpdateData ()
+	)
+
+	fn call_do_it =
+	(
+		local result
+
+		-- One more project
+		fileParsed = fileParsed + 1
+
+		-- Call it
+		result = do_it ()
+
+		-- Error ?
+		if result < 0 then
+			countErrors = countErrors + 1
+		else 
+			countModifications = countModifications + result
+
+		-- Return result
+		return result
+	)
+
+	fn BackupFile file =
+	(
+		local i
+		local newFilename
+
+		i = 0
+		while true do
+		(
+			-- New file name
+			newFilename = file + ".backup_" + (i as string)
+
+			-- File exist ?
+			if (fileExist newFilename) == false then
+			(
+				if (copyFile file newFilename) == false then 
+					return false
+				else 
+					return true
+			)
+			i = i + 1
+		)
+	)
+
+	fn RecurseFolder currentDirectory =
+	(
+		resetMAXFile #noprompt
+		
+		local result
+		local file
+		local files
+		local origAnimStart
+		local origAnimEnd
+		local origFrameRate
+		
+		-- Parse files
+		files = getFiles (currentDirectory+"/*.max")
+		
+		-- For each files
+		for i = 1 to files.count do
+		(
+			-- File name
+			file = files[i]
+			
+			-- Progress bar
+			ProgressText.text  = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\""
+			Progress.value = i*100/files.count
+			
+			if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then
+			(
+				resetMAXFile #noprompt
+				
+				nllog("CONVERT " + file)
+				
+				-- Open the max project
+				if loadMaxFile file quiet:true == true then
+				(
+					origAnimStart = animationRange.start
+					origAnimEnd = animationRange.end
+					origFrameRate = frameRate
+					
+					nllog("TIMING -- " + file + " -- " + (origAnimStart as string) + " -- " + (origAnimEnd as string) + " -- " + (origFrameRate as string))
+				)
+			)
+			else
+			(
+				nllog("SKIP " + file + " by tag")
+			)
+		)
+		
+		-- Parse sub directory ?
+		if (Recurse.checked == true) then
+		(
+			local directories
+
+			-- Get the directories
+			directories = getDirectories (currentDirectory+"/*")
+
+			-- For each directories
+			for dir in directories do
+			(
+				RecurseFolder dir
+			)
+		)
+	)
+	
+	on BrowseDirectory pressed do
+	(
+		local dir
+		try
+		(
+			dir = getSavePath () -- caption:"Select the projects directory"
+			if dir != undefined then
+				Directory.text = dir
+		)
+		catch 
+		(
+		)
+	)
+	
+	on GoButton pressed do
+	(
+		-- Reset count
+		countModifications = 0
+		countErrors = 0
+		fileModified = 0
+		fileParsed = 0
+		
+		-- Get files in the shape_source_directory
+		if SourceFiles.state == 2 then
+		(
+			-- Should warning user ?
+			if (SourceFiles.state == 2) and (Test.checked == false) then
+			(
+				-- Warning !
+				if ((queryBox "Warning, all the files in the specified folders will be overwrited.\nYou should backup your files before executing this script.\nDo you want to continue executing this script ?" beep:true) == true) then
+					RecurseFolder (adjustPathStringForScript Directory.text)
+			)
+			else
+			(
+				RecurseFolder (adjustPathStringForScript Directory.text)
+			)
+		)
+		else
+		(
+			-- Just compute the current project
+			call_do_it ()
+		)
+		
+		-- Show errors
+		ProgressText.text  = (fileParsed as string) + " project(s) opened, " + (countModifications as string) + " project modification(s), " + (fileModified as string) + " project(s) saved, " + (countErrors as string) + " error(s)."
+		Progress.value = 100
+	)
+)
+
+assets_resave_floater = newRolloutFloater "NeL Assets Timings Database" 550 874
+addrollout assets_resave_rollout assets_resave_floater rolledUp:false
+

From d5a06c1a62b778a9b36b723d9ac709dcc411d41b Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Thu, 25 Apr 2019 02:57:07 +0800
Subject: [PATCH 10/75] Add recent 3ds Max SDK paths

---
 code/CMakeModules/Find3dsMaxSDK.cmake | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/code/CMakeModules/Find3dsMaxSDK.cmake b/code/CMakeModules/Find3dsMaxSDK.cmake
index cf49a90d3..de4eb5f01 100644
--- a/code/CMakeModules/Find3dsMaxSDK.cmake
+++ b/code/CMakeModules/Find3dsMaxSDK.cmake
@@ -16,9 +16,28 @@ FIND_PATH(MAXSDK_DIR
   HINTS
   "$ENV{MAXSDK_DIR}"
   PATHS
+  "$ENV{ADSK_3DSMAX_SDK_2021}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2020}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2019}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2018}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2017}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2016}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2015}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2014}/maxsdk"
+  "$ENV{ADSK_3DSMAX_SDK_2013}/maxsdk"
   "$ENV{ADSK_3DSMAX_SDK_2012}/maxsdk"
   "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2021 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2020 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2019 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2018 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2017 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2016 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2015 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2014 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2013 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2012 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2011 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2010 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2009 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2008 SDK/maxsdk"

From 0174001273d8b8af5ae2e18ccdafb2e07d0404b2 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 03:05:31 +0800
Subject: [PATCH 11/75] Correct 3ds Max SDK paths on 64bit host

---
 code/CMakeModules/Find3dsMaxSDK.cmake | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/code/CMakeModules/Find3dsMaxSDK.cmake b/code/CMakeModules/Find3dsMaxSDK.cmake
index de4eb5f01..7bcecb84b 100644
--- a/code/CMakeModules/Find3dsMaxSDK.cmake
+++ b/code/CMakeModules/Find3dsMaxSDK.cmake
@@ -11,6 +11,8 @@ if(MAXSDK_INCLUDE_DIR)
   SET(MAXSDK_FIND_QUIETLY TRUE)
 endif()
 
+set(_pf_x86 "PROGRAMFILES(x86)")
+
 FIND_PATH(MAXSDK_DIR
   "include/maxversion.h"
   HINTS
@@ -27,6 +29,21 @@ FIND_PATH(MAXSDK_DIR
   "$ENV{ADSK_3DSMAX_SDK_2013}/maxsdk"
   "$ENV{ADSK_3DSMAX_SDK_2012}/maxsdk"
   "$ENV{3DSMAX_2011_SDK_PATH}/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2021 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2020 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2019 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2018 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2017 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2016 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2015 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2014 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2013 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2012 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2011 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2010 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2009 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 2008 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3ds Max 9 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2021 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2020 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2019 SDK/maxsdk"

From 705ad16d93d1d6d1beccad67825fd6e0049228c0 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 03:31:26 +0800
Subject: [PATCH 12/75] VS2008 can't compile dr_mp3.h

---
 code/nel/include/nel/sound/audio_decoder_mp3.h | 4 ++++
 code/nel/src/sound/audio_decoder.cpp           | 2 ++
 code/nel/src/sound/audio_decoder_mp3.cpp       | 4 ++++
 3 files changed, 10 insertions(+)

diff --git a/code/nel/include/nel/sound/audio_decoder_mp3.h b/code/nel/include/nel/sound/audio_decoder_mp3.h
index fac2e2693..e6ef91326 100644
--- a/code/nel/include/nel/sound/audio_decoder_mp3.h
+++ b/code/nel/include/nel/sound/audio_decoder_mp3.h
@@ -18,6 +18,8 @@
 #define NLSOUND_AUDIO_DECODER_MP3_H
 #include <nel/misc/types_nl.h>
 
+#if (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
+
 #include <nel/sound/audio_decoder.h>
 
 // disable drmp3_init_file()
@@ -91,6 +93,8 @@ public:
 
 } /* namespace NLSOUND */
 
+#endif /* (NL_COMP_VC_VERSION > 90) */
+
 #endif // NLSOUND_AUDIO_DECODER_MP3_H
 
 /* end of file */
diff --git a/code/nel/src/sound/audio_decoder.cpp b/code/nel/src/sound/audio_decoder.cpp
index d849ed770..506c01a3b 100644
--- a/code/nel/src/sound/audio_decoder.cpp
+++ b/code/nel/src/sound/audio_decoder.cpp
@@ -103,10 +103,12 @@ IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC
 	{
 		return new CAudioDecoderVorbis(stream, loop);
 	}
+#if (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
 	else if (type_lower == "mp3")
 	{
 		return new CAudioDecoderMP3(stream, loop);
 	}
+#endif
 	else
 	{
 		nlwarning("Music file type unknown: '%s'", type_lower.c_str());
diff --git a/code/nel/src/sound/audio_decoder_mp3.cpp b/code/nel/src/sound/audio_decoder_mp3.cpp
index dc740bec0..fd8b1721c 100644
--- a/code/nel/src/sound/audio_decoder_mp3.cpp
+++ b/code/nel/src/sound/audio_decoder_mp3.cpp
@@ -17,6 +17,8 @@
 
 #include "stdsound.h"
 
+#if (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
+
 #include <nel/sound/audio_decoder_mp3.h>
 
 #define DR_MP3_IMPLEMENTATION
@@ -221,4 +223,6 @@ void CAudioDecoderMP3::setLooping(bool loop)
 
 } /* namespace NLSOUND */
 
+#endif /* (NL_COMP_VC_VERSION > 90) */
+
 /* end of file */

From c28d611a171624509058290944345df0ec78d7ce Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 03:33:36 +0800
Subject: [PATCH 13/75] VS2008 can't compile dr_mp3.h

---
 code/nel/src/sound/audio_decoder.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/code/nel/src/sound/audio_decoder.cpp b/code/nel/src/sound/audio_decoder.cpp
index 506c01a3b..f56f16a2e 100644
--- a/code/nel/src/sound/audio_decoder.cpp
+++ b/code/nel/src/sound/audio_decoder.cpp
@@ -146,6 +146,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
 
 		nlwarning("Unable to open: '%s'", filepath.c_str());
 	}
+#if (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
 	else if (type_lower == "mp3")
 	{
 		CIFile ifile;
@@ -156,6 +157,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
 
 		nlwarning("Unable to open: '%s'", filepath.c_str());
 	}
+#endif
 	else
 	{
 		nlwarning("Music file type unknown: '%s'", type_lower.c_str());

From 2156ebaef5fda422236cc2ec53a1a79ba7a7fa7e Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 03:49:37 +0800
Subject: [PATCH 14/75] Build fixes for VS2008

---
 code/nel/include/nel/misc/common.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index d5d59b130..4a1cafc23 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -313,7 +313,17 @@ inline sint nlstricmp(const char *lhs, const std::string &rhs) { return stricmp(
 #define utf8ToTStr(str) ((wchar_t*)ucstring::makeFromUtf8(str).c_str())
 #else
 #define tStrToUtf8(str) (std::string((LPCSTR)str))
-#define utf8ToTStr(str) (str.c_str())
+inline const char *nlutf8ToTStr(const char *str) { return str; }
+inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
+#define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
+#endif
+
+#if (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
+float nlroundf(float x)
+{
+   return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
+}
+#define roundf(x) NLMISC::nlroundf(x)
 #endif
 
 // wrapper for fopen to be able to open files with an UTF-8 filename

From 5ddf4ee4d8877fea6c5a55ca8807f563f11d9b75 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 10:49:26 +0800
Subject: [PATCH 15/75] Don't pass conversions to output pointers

---
 code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
index 5ccc223f9..5d23c25fa 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
@@ -2524,13 +2524,13 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB
 		// Assign the name of the lightmap and get the complete save name
 			
 		// Get the name of the max project
-		char projectName[512];
-		_wsplitpath (_Ip->GetCurFileName(), NULL, NULL, utf8ToTStr(projectName), NULL);
+		ucchar projectName[512];
+		_wsplitpath(WStr(_Ip->GetCurFileName()), NULL, NULL, (wchar_t *)projectName, NULL);
 
 		// Add lightmap information in the lightmap log
 		COFile outputLog;
 		if (outputLightmapLog)
-			createLightmapLog (outputLog, gOptions.sExportLighting.c_str(), projectName, tStrToUtf8(ZeNode.GetName()).c_str());
+			createLightmapLog(outputLog, gOptions.sExportLighting.c_str(), ucstring(projectName).toUtf8(), CStr(ZeNode.GetName()).data());
 
 		// Update UV coords to Texture space
 		PutFaceUV1InTextureCoord( LightMap.w, LightMap.h, AllFaces.begin(), AllFaces.size() );

From bd21bfeeb3011cdad089fd5bf481a4046bff6877 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 10:50:45 +0800
Subject: [PATCH 16/75] Typo

---
 code/nel/include/nel/misc/common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index 4a1cafc23..0549d1bcf 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -318,7 +318,7 @@ inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
 #define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
 #endif
 
-#if (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
+#if (NL_COMP_VC_VERSION <= 90) /* VS2008 does not have stdint.h */
 float nlroundf(float x)
 {
    return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);

From 449f0061f86f851e1806d61ed86d17815df7cbfa Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 16:25:19 +0800
Subject: [PATCH 17/75] Fix build for Max 2010 plugins on VS2008

---
 code/nel/include/nel/misc/common.h            |  14 +-
 .../tools/3d/ligo/plugin_max/max_to_ligo.cpp  |  15 +-
 code/nel/tools/3d/ligo/plugin_max/script.cpp  |  24 ++--
 .../plugin_max/nel_3dsmax_shared/StdAfx.cpp   |   2 +
 .../nel_3dsmax_shared/nel_3dsmax_shared.cpp   |   2 +
 .../nel_3dsmax_shared/nel_3dsmax_shared.h     |   2 +
 .../nel_3dsmax_shared/string_common.h         |  75 ++++++++++
 .../3d/plugin_max/nel_export/nel_export.cpp   |  68 ++++-----
 .../nel_export/nel_export_export.cpp          |   2 +-
 .../nel_export/nel_export_filetools.cpp       |  10 +-
 .../nel_export/nel_export_node_properties.cpp | 132 +++++++++---------
 .../nel_export/nel_export_scene.cpp           |   2 +-
 .../nel_export/nel_export_script.cpp          |  60 ++++----
 .../plugin_max/nel_export/nel_export_swt.cpp  |   6 +-
 .../plugin_max/nel_export/nel_export_view.cpp |   8 +-
 .../3d/plugin_max/nel_export/progress.cpp     |   2 +-
 .../3d/plugin_max/nel_export/std_afx.cpp      |   3 +-
 .../tools/3d/plugin_max/nel_export/std_afx.h  |   2 +
 .../3d/plugin_max/nel_mesh_lib/StdAfx.cpp     |   2 +
 .../3d/plugin_max/nel_mesh_lib/calc_lm.cpp    |  20 +--
 .../3d/plugin_max/nel_mesh_lib/calc_lm_rt.cpp |   4 +-
 .../plugin_max/nel_mesh_lib/export_anim.cpp   |   6 +-
 .../nel_mesh_lib/export_collision.cpp         |   2 +-
 .../nel_mesh_lib/export_material.cpp          |   6 +-
 .../plugin_max/nel_mesh_lib/export_mesh.cpp   |  48 +++----
 .../nel_mesh_lib/export_mesh_interface.cpp    |  18 +--
 .../plugin_max/nel_mesh_lib/export_misc.cpp   |  56 ++++----
 .../nel_mesh_lib/export_particle_system.cpp   |   4 +-
 .../nel_mesh_lib/export_radial_normal.cpp     |   2 +-
 .../plugin_max/nel_mesh_lib/export_scene.cpp  |  16 +--
 .../plugin_max/nel_mesh_lib/export_script.cpp |   2 +-
 .../nel_mesh_lib/export_skinning.cpp          |   8 +-
 .../plugin_max/nel_patch_converter/PO2RPO.h   |   8 +-
 .../nel_patch_converter.cpp                   |  10 +-
 .../plugin_max/nel_patch_converter/script.cpp |  10 +-
 .../3d/plugin_max/nel_patch_edit/editpat.h    |   4 +-
 .../nel_patch_edit/np_edit_patch_mod.cpp      |   2 +-
 .../3d/plugin_max/nel_patch_edit/stdafx.cpp   |   2 +
 .../nel_patch_lib/nel_patch_mesh.cpp          |  19 ++-
 .../plugin_max/nel_patch_lib/nel_patch_mesh.h |   3 +-
 .../tools/3d/plugin_max/nel_patch_lib/rpo.cpp |   2 +-
 .../tools/3d/plugin_max/nel_patch_lib/rpo.h   |   6 +-
 .../3d/plugin_max/nel_patch_lib/rpo2nel.cpp   |  24 ++--
 .../3d/plugin_max/nel_patch_lib/stdafx.cpp    |   4 +-
 .../nel_patch_paint/nel_patch_paint.h         |   4 +-
 .../3d/plugin_max/nel_patch_paint/paint.cpp   |  20 +--
 .../plugin_max/nel_patch_paint/paint_ui.cpp   |   8 +-
 .../nel_patch_paint/paint_vcolor.cpp          |   4 +-
 .../3d/plugin_max/nel_patch_paint/stdafx.cpp  |   2 +
 .../vertex_tree_paint.cpp                     |   2 +-
 .../nel_vertex_tree_paint/vertex_tree_paint.h |   5 +-
 .../3d/plugin_max/tile_utility/rgbadd.cpp     |  22 +--
 .../plugin_max/tile_utility/tile_utility.cpp  |  16 ++-
 .../3d/plugin_max/tile_utility/tile_utility.h |   2 +
 54 files changed, 455 insertions(+), 347 deletions(-)
 create mode 100644 code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index 0549d1bcf..150780877 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -303,30 +303,32 @@ inline sint nlstricmp(const std::string &lhs, const std::string &rhs) { return s
 inline sint nlstricmp(const std::string &lhs, const char *rhs) { return stricmp(lhs.c_str(),rhs); }
 inline sint nlstricmp(const char *lhs, const std::string &rhs) { return stricmp(lhs,rhs.c_str()); }
 
-// macros helper to convert UTF-8 std::string and wchar_t*
+// TODO: Can we prefix these with 'nl' like other methods?
+// Macros helper to convert UTF-8 std::string and wchar_t*
 #define wideToUtf8(str) (ucstring((ucchar*)str).toUtf8())
 #define utf8ToWide(str) ((wchar_t*)ucstring::makeFromUtf8(str).c_str())
 
-// macros helper to convert UTF-8 std::string and TCHAR*
+// Macros helper to convert UTF-8 std::string and TCHAR*
 #ifdef _UNICODE
 #define tStrToUtf8(str) (ucstring((ucchar*)(LPCWSTR)str).toUtf8())
-#define utf8ToTStr(str) ((wchar_t*)ucstring::makeFromUtf8(str).c_str())
+#define utf8ToTStr(str) ((const wchar_t *)ucstring::makeFromUtf8(str).c_str())
 #else
+// FIXME: This is not accurate, it should be a conversion between local charset and utf8
 #define tStrToUtf8(str) (std::string((LPCSTR)str))
 inline const char *nlutf8ToTStr(const char *str) { return str; }
 inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
 #define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
 #endif
 
-#if (NL_COMP_VC_VERSION <= 90) /* VS2008 does not have stdint.h */
-float nlroundf(float x)
+#if (NL_COMP_VC_VERSION <= 90)
+inline float nlroundf(float x)
 {
    return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
 }
 #define roundf(x) NLMISC::nlroundf(x)
 #endif
 
-// wrapper for fopen to be able to open files with an UTF-8 filename
+// Wrapper for fopen to be able to open files with an UTF-8 filename
 FILE* nlfopen(const std::string &filename, const std::string &mode);
 
 /** Signed 64 bit fseek. Same interface as fseek
diff --git a/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp b/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp
index 44b43beed..a4d41649f 100644
--- a/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp
+++ b/code/nel/tools/3d/ligo/plugin_max/max_to_ligo.cpp
@@ -38,6 +38,8 @@
 #include "nel/ligo/ligo_error.h"
 #include "nel/misc/path.h"
 
+#include "../../plugin_max/nel_3dsmax_shared/string_common.h"
+
 using namespace std;
 using namespace NLMISC;
 extern HINSTANCE hInstance;
@@ -126,13 +128,13 @@ bool CMaxToLigo::loadLigoConfigFile (CLigoConfig& config, Interface& it, bool di
 	{
 		// Get the path
 		TCHAR sModulePath[256];
-		int res=GetModuleFileName(hModule, sModulePath, 256);
+		int res = GetModuleFileName(hModule, sModulePath, 256);
 
 		// Success ?
 		if (res)
 		{
 			// Path
-			std::string path = NLMISC::CFile::getPath(tStrToUtf8(sModulePath) + "ligoscape.cfg");
+			std::string path = NLMISC::CFile::getPath(MCharStrToUtf8(sModulePath) + "ligoscape.cfg");
 
 			try
 			{
@@ -164,16 +166,19 @@ void CMaxToLigo::errorMessage(const std::string &msg, const std::string &title,
 	if (dialog)
 	{
 		// Dialog message
-		MessageBox (it.GetMAXHWnd(), utf8ToTStr(msg), utf8ToTStr(title), MB_OK|MB_ICONEXCLAMATION);
+		ucstring ucmsg, uctitle;
+		ucmsg.fromUtf8(msg);
+		uctitle.fromUtf8(title);
+		MessageBoxW(it.GetMAXHWnd(), (LPCWSTR)ucmsg.c_str(), (LPCWSTR)uctitle.c_str(), MB_OK | MB_ICONEXCLAMATION);
 	}
 	else
 	{
 		// Text message
-		mprintf (utf8ToTStr(msg + "\n"));
+		mprintf(_M("%s\n"), MaxTStrFromUtf8(msg).data());
 	}
 
 	// Output in log
-	nlwarning ("LIGO ERROR : %s", msg.c_str());
+	nlwarning("LIGO ERROR : %s", msg.c_str());
 }
 
 // ***************************************************************************
diff --git a/code/nel/tools/3d/ligo/plugin_max/script.cpp b/code/nel/tools/3d/ligo/plugin_max/script.cpp
index 7083a22a7..15c180192 100644
--- a/code/nel/tools/3d/ligo/plugin_max/script.cpp
+++ b/code/nel/tools/3d/ligo/plugin_max/script.cpp
@@ -155,7 +155,7 @@ Value* export_material_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// The second arg
-	const std::string fileName = tStrToUtf8(arg_list[1]->to_string());
+	const std::string fileName = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// The third arg
 	bool checkOnly = (arg_list[2]->to_bool() != FALSE);
@@ -321,12 +321,12 @@ Value* export_transition_cf (Value** arg_list, int count)
 	nlassert (is_array(nodes));
 
 	// The second arg
-	std::string fileName = tStrToUtf8(arg_list[1]->to_string());
+	std::string fileName = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// The second arg
 	string matFilename[2];
-	matFilename[0] = tStrToUtf8(arg_list[2]->to_string());
-	matFilename[1] = tStrToUtf8(arg_list[3]->to_string());
+	matFilename[0] = MCharStrToUtf8(arg_list[2]->to_string());
+	matFilename[1] = MCharStrToUtf8(arg_list[3]->to_string());
 
 	// The third arg
 	bool checkOnly = (arg_list[4]->to_bool() != FALSE);
@@ -696,7 +696,7 @@ Value* check_zone_with_material_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// The second arg
-	string fileName = tStrToUtf8(arg_list[1]->to_string());
+	string fileName = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// The fourth arg
 	bool errorInDialog = (arg_list[2]->to_bool() != FALSE);
@@ -830,7 +830,7 @@ Value* check_zone_with_transition_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// The second arg
-	string fileName = tStrToUtf8(arg_list[1]->to_string());
+	string fileName = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// The second arg
 	int transitionNumber = arg_list[2]->to_int();
@@ -998,7 +998,7 @@ Value* export_zone_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// The second arg
-	string fileName = tStrToUtf8(arg_list[1]->to_string());
+	string fileName = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// The thrid arg
 	Array *array = (Array*)arg_list[2];
@@ -1043,8 +1043,8 @@ Value* export_zone_cf (Value** arg_list, int count)
 			type_check (cell->get(2), String, message);
 
 			// Get the strings
-			categories[i].first = tStrToUtf8(cell->get(1)->to_string());
-			categories[i].second = tStrToUtf8(cell->get(2)->to_string());
+			categories[i].first = MCharStrToUtf8(cell->get(1)->to_string());
+			categories[i].second = MCharStrToUtf8(cell->get(2)->to_string());
 		}
 
 		// Get a Object pointer
@@ -1352,7 +1352,7 @@ Value* get_error_string_cf (Value** arg_list, int count)
 	int errorCode = arg_list[0]->to_int()-1;
 
 	// Error code
-	return new String (utf8ToTStr(CLigoError::getStringError ((CLigoError::TError)errorCode)));
+	return new String(MaxTStrFromUtf8(CLigoError::getStringError ((CLigoError::TError)errorCode)));
 }
 
 // ***************************************************************************
@@ -1367,7 +1367,7 @@ Value* set_directory_cf (Value** arg_list, int count)
 	type_check(arg_list[0], String, message);
 
 	// The first arg
-	const std::string dir = tStrToUtf8(arg_list[0]->to_string());
+	const std::string dir = MCharStrToUtf8(arg_list[0]->to_string());
 
 	// Set the directory
 	return (chdir (dir.c_str())==0)?&true_value:&false_value;
@@ -1859,7 +1859,7 @@ Value* make_snapshot_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// The second arg
-	string fileName = tStrToUtf8(arg_list[1]->to_string());
+	string fileName = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// The thrid arg
 	int xMin = arg_list[2]->to_int();
diff --git a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/StdAfx.cpp b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/StdAfx.cpp
index ea4148a46..e0a8e62f6 100644
--- a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/StdAfx.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/StdAfx.cpp
@@ -18,3 +18,5 @@
 // and not in this file
 
 #include "stdafx.h"
+
+void nlmax_shared_stdafx_dummy() { }
diff --git a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.cpp b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.cpp
index 76592f556..3b73a3533 100644
--- a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.cpp
@@ -72,3 +72,5 @@ NEL_3DSMAX_SHARED_API NLMISC::INelContext &GetSharedNelContext()
 	}
 	return NLMISC::INelContext::getInstance();
 }
+
+/* end of file */
diff --git a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.h b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.h
index 1d7b4ceba..19ebdf817 100644
--- a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.h
+++ b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/nel_3dsmax_shared.h
@@ -25,3 +25,5 @@ class CPatchAllocator;
 extern NEL_3DSMAX_SHARED_API CPatchAllocator& GetAllocator();
 
 extern NEL_3DSMAX_SHARED_API NLMISC::INelContext &GetSharedNelContext();
+
+/* end of file */
diff --git a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h
new file mode 100644
index 000000000..7b046abbd
--- /dev/null
+++ b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h
@@ -0,0 +1,75 @@
+// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
+// Copyright (C) 2010  Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef NLMAX_STRING_COMMON_H
+#define NLMAX_STRING_COMMON_H
+
+#include <nel/misc/ucstring.h>
+
+#if (MAX_VERSION_MAJOR < 15)
+#define GET_OBJECT_NAME_CONST
+#define NOTIFY_REF_PARAMS Interval changeInt, RefTargetHandle hTarget, PartID& partID,  RefMessage message
+#define NOTIFY_REF_PROPAGATE , BOOL propagate
+#define nl_p_end end
+#else
+#define GET_OBJECT_NAME_CONST const
+#define NOTIFY_REF_PARAMS const Interval &changeInt, RefTargetHandle hTarget, PartID& partID,  RefMessage message, BOOL propagate
+#define nl_p_end p_end
+#endif
+
+static TSTR MaxTStrFromUtf8(const std::string &src)
+{
+	TSTR dst;
+#if (MAX_VERSION_MAJOR < 15)
+	ucstring uc;
+	uc.fromUtf8(src);
+	dst = (const mwchar_t *)uc.c_str();
+#else
+	dst.FromUTF8(source);
+#endif
+	return dst;
+}
+
+static std::string MaxTStrToUtf8(const TSTR& src)
+{
+#if (MAX_VERSION_MAJOR < 15)
+#ifdef _UNICODE
+	ucstring uc(src.data());
+	return uc.toUtf8();
+#else
+	WStr ws = src;
+	ucstring uc((const ucchar *)ws.data());
+	return uc.toUtf8();
+#endif
+#else
+	return src.ToUTF8();
+#endif
+}
+
+static std::string MCharStrToUtf8(const MCHAR *src)
+{
+#ifdef _UNICODE
+	ucstring uc((const ucchar *)src);
+	return uc.toUtf8();
+#else
+	ucstring uc((const ucchar *)WStr(src).data());
+	return uc.toUtf8();
+#endif
+}
+
+#endif /* #ifndef NLMAX_STRING_COMMON_H */
+
+/* end of file */
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp
index 4482ab51f..a44167294 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export.cpp
@@ -94,7 +94,7 @@ INT_PTR CALLBACK OptionsDialogCallback (
 			else
 				SendMessage( GetDlgItem(hwndDlg,IDC_SHADOW), BM_SETCHECK, BST_UNCHECKED, 0 );
 
-			SendMessage( GetDlgItem(hwndDlg,IDC_EDITEXPORTLIGHTING), WM_SETTEXT, 0, (LPARAM)utf8ToTStr(theExportSceneStruct.sExportLighting));
+			SendMessage( GetDlgItem(hwndDlg,IDC_EDITEXPORTLIGHTING), WM_SETTEXT, 0, (LPARAM)MaxTStrFromUtf8(theExportSceneStruct.sExportLighting).data());
 
 			if( theExportSceneStruct.nExportLighting == 0 )
 				SendMessage( GetDlgItem(hwndDlg,IDC_RADIONORMALEXPORTLIGHTING), BM_SETCHECK, BST_CHECKED, 0 );
@@ -102,7 +102,7 @@ INT_PTR CALLBACK OptionsDialogCallback (
 			if( theExportSceneStruct.nExportLighting == 1 )
 				SendMessage( GetDlgItem(hwndDlg,IDC_RADIORADIOSITYEXPORTLIGHTING), BM_SETCHECK, BST_CHECKED, 0 );
 
-			SendMessage( GetDlgItem(hwndDlg,IDC_EDITLUMELSIZE), WM_SETTEXT, 0, (LPARAM)utf8ToTStr(toString(theExportSceneStruct.rLumelSize)));
+			SendMessage( GetDlgItem(hwndDlg,IDC_EDITLUMELSIZE), WM_SETTEXT, 0, (LPARAM)MaxTStrFromUtf8(toString(theExportSceneStruct.rLumelSize)).data());
 
 			if( theExportSceneStruct.nOverSampling == 1 )
 				SendMessage( GetDlgItem(hwndDlg,IDC_RADIOSS1), BM_SETCHECK, BST_CHECKED, 0 );
@@ -132,8 +132,8 @@ INT_PTR CALLBACK OptionsDialogCallback (
 			else
 				SendMessage( GetDlgItem(hwndDlg,IDC_TEST_SURFACE_LIGHT), BM_SETCHECK, BST_UNCHECKED, 0 );
 
-			SendMessage( GetDlgItem(hwndDlg,IDC_EDITCELLSIZE), WM_SETTEXT, 0, (LPARAM)utf8ToTStr(toString(theExportSceneStruct.SurfaceLightingCellSize)));
-			SendMessage( GetDlgItem(hwndDlg,IDC_EDITCELLDELTAZ), WM_SETTEXT, 0, (LPARAM)utf8ToTStr(toString(theExportSceneStruct.SurfaceLightingDeltaZ)));
+			SendMessage( GetDlgItem(hwndDlg,IDC_EDITCELLSIZE), WM_SETTEXT, 0, (LPARAM)MaxTStrFromUtf8(toString(theExportSceneStruct.SurfaceLightingCellSize)).data());
+			SendMessage( GetDlgItem(hwndDlg,IDC_EDITCELLDELTAZ), WM_SETTEXT, 0, (LPARAM)MaxTStrFromUtf8(toString(theExportSceneStruct.SurfaceLightingDeltaZ)).data());
 
 		}
 		break;
@@ -148,7 +148,7 @@ INT_PTR CALLBACK OptionsDialogCallback (
 					if( theCNelExport.SelectDir(hwndDlg, _T("LightMaps Directory"), sTemp ) )
 					{
 						theExportSceneStruct.sExportLighting = sTemp;
-						SendMessage( GetDlgItem(hwndDlg, IDC_EDITEXPORTLIGHTING), WM_SETTEXT, 0, (LPARAM)utf8ToTStr(theExportSceneStruct.sExportLighting) );
+						SendMessage(GetDlgItem(hwndDlg, IDC_EDITEXPORTLIGHTING), WM_SETTEXT, 0, (LPARAM)MaxTStrFromUtf8(theExportSceneStruct.sExportLighting).data());
 					}
 				}
 				break;
@@ -180,7 +180,7 @@ INT_PTR CALLBACK OptionsDialogCallback (
 
 					TCHAR tmp[1024];
 					SendMessage( GetDlgItem(hwndDlg,IDC_EDITEXPORTLIGHTING), WM_GETTEXT, 1024, (LPARAM)tmp );
-					theExportSceneStruct.sExportLighting = tStrToUtf8(tmp);
+					theExportSceneStruct.sExportLighting = MCharStrToUtf8(tmp);
 
 					if( SendMessage( GetDlgItem(hwndDlg,IDC_RADIONORMALEXPORTLIGHTING), BM_GETCHECK, 0, 0 ) == BST_CHECKED )
 						theExportSceneStruct.nExportLighting = 0;
@@ -189,7 +189,7 @@ INT_PTR CALLBACK OptionsDialogCallback (
 						theExportSceneStruct.nExportLighting = 1;
 
 					SendMessage( GetDlgItem(hwndDlg,IDC_EDITLUMELSIZE), WM_GETTEXT, 1024, (LPARAM)tmp );
-					NLMISC::fromString(tStrToUtf8(tmp), theExportSceneStruct.rLumelSize);
+					NLMISC::fromString(MCharStrToUtf8(tmp), theExportSceneStruct.rLumelSize);
 
 					if( SendMessage( GetDlgItem(hwndDlg,IDC_RADIOSS1), BM_GETCHECK, 0, 0 ) == BST_CHECKED )
 						theExportSceneStruct.nOverSampling = 1;
@@ -214,10 +214,10 @@ INT_PTR CALLBACK OptionsDialogCallback (
 					theExportSceneStruct.bTestSurfaceLighting= (SendMessage( GetDlgItem(hwndDlg,IDC_TEST_SURFACE_LIGHT), BM_GETCHECK, 0, 0 ) == BST_CHECKED);
 
 					SendMessage( GetDlgItem(hwndDlg,IDC_EDITCELLSIZE), WM_GETTEXT, 1024, (LPARAM)tmp );
-					NLMISC::fromString(tStrToUtf8(tmp), theExportSceneStruct.SurfaceLightingCellSize);
+					NLMISC::fromString(MCharStrToUtf8(tmp), theExportSceneStruct.SurfaceLightingCellSize);
 
 					SendMessage( GetDlgItem(hwndDlg,IDC_EDITCELLDELTAZ), WM_GETTEXT, 1024, (LPARAM)tmp );
-					NLMISC::fromString(tStrToUtf8(tmp), theExportSceneStruct.SurfaceLightingDeltaZ);
+					NLMISC::fromString(MCharStrToUtf8(tmp), theExportSceneStruct.SurfaceLightingDeltaZ);
 
 					// End the dialog
 					EndDialog(hwndDlg, TRUE);
@@ -354,7 +354,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 						if (RPO::isZone (*pNode, time))
 						{
 							// Save path
-							std::string sSavePath = tStrToUtf8(pNode->GetName());
+							std::string sSavePath = MCharStrToUtf8(pNode->GetName());
 
 							// Choose a file to export
 							if (!CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_DONTEXPORT, 0))
@@ -364,15 +364,15 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 								if (!theCNelExport.exportZone (sSavePath, *pNode, time))
 								{
 									// Error message
-									std::string sErrorMsg = toString("Error exporting the zone %s in the file\n%s", tStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
-									MessageBox (hWnd, utf8ToTStr(sErrorMsg), L"NeL export", MB_OK|MB_ICONEXCLAMATION);
+									std::string sErrorMsg = toString("Error exporting the zone %s in the file\n%s", MCharStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
+									MessageBox (hWnd, MaxTStrFromUtf8(sErrorMsg), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
 								}
 							}
 						}
 						else if (CExportNel::isVegetable (*pNode, time))
 						{
 							// Save path
-							std::string sSavePath = tStrToUtf8(pNode->GetName());
+							std::string sSavePath = MCharStrToUtf8(pNode->GetName());
 
 							// Choose a file to export
 							if (!CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_DONTEXPORT, 0))
@@ -382,8 +382,8 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 								if (!theCNelExport.exportVegetable (sSavePath.c_str(), *pNode, time))
 								{
 									// Error message
-									std::string sErrorMsg = toString("Error exporting the vegetable %s in the file\n%s", tStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
-									MessageBox (hWnd, utf8ToTStr(sErrorMsg), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
+									std::string sErrorMsg = toString("Error exporting the vegetable %s in the file\n%s", MCharStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
+									MessageBox (hWnd, MaxTStrFromUtf8(sErrorMsg), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
 								}
 							}
 						}
@@ -391,7 +391,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 						else if (CExportNel::isLodCharacter (*pNode, time))
 						{
 							// Save path
-							std::string sSavePath = tStrToUtf8(pNode->GetName());
+							std::string sSavePath = MCharStrToUtf8(pNode->GetName());
 
 							// Choose a file to export
 							if (!CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_DONTEXPORT, 0))
@@ -401,8 +401,8 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 								if (!theCNelExport.exportLodCharacter (sSavePath, *pNode, time))
 								{
 									// Error message
-									std::string sErrorMsg = toString("Error exporting the lod character %s in the file\n%s", tStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
-									MessageBox (hWnd, utf8ToTStr(sErrorMsg), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
+									std::string sErrorMsg = toString("Error exporting the lod character %s in the file\n%s", MCharStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
+									MessageBox (hWnd, MaxTStrFromUtf8(sErrorMsg).data(), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
 								}
 							}
 						}
@@ -410,7 +410,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 						else if (CExportNel::isMesh (*pNode, time))
 						{
 							// Save path
-							std::string sSavePath = tStrToUtf8(pNode->GetName());
+							std::string sSavePath = MCharStrToUtf8(pNode->GetName());
 
 							// Choose a file to export
 							if (!CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_DONTEXPORT, 0))
@@ -424,8 +424,8 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 								if (!theCNelExport.exportMesh (sSavePath, *pNode, time))
 								{
 									// Error message
-									std::string sErrorMsg = toString("Error exporting the mesh %s in the file\n%s", tStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
-									MessageBox (hWnd, utf8ToTStr(sErrorMsg), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
+									std::string sErrorMsg = toString("Error exporting the mesh %s in the file\n%s", MCharStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
+									MessageBox (hWnd, MaxTStrFromUtf8(sErrorMsg).data(), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
 								}
 								// Delete the skeleton pointer
 								if (pSkinShape)
@@ -463,7 +463,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 						// Name of the node
 
 						// Save path
-						std::string sSavePath = tStrToUtf8((*vectNode.begin())->GetName());
+						std::string sSavePath = MCharStrToUtf8((*vectNode.begin())->GetName());
 
 						// Choose a file to export
 						if (theCNelExport.SelectFileForSave (hWnd, _T("Save animations..."), (LOWORD(wParam)==ID_SAVE_MODEL_ANIM)?animModelFilter:animModelFilter,
@@ -473,8 +473,8 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 							if (!theCNelExport.exportAnim (sSavePath, vectNode, time, LOWORD(wParam)==ID_SAVE_SCENE_ANIM))
 							{
 								// Error message
-								std::string sErrorMsg = toString("Error exporting animation %s in the file\n%s", tStrToUtf8((*vectNode.begin())->GetName()).c_str(), sSavePath.c_str());
-								MessageBox(hWnd, utf8ToTStr(sErrorMsg), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
+								std::string sErrorMsg = toString("Error exporting animation %s in the file\n%s", MCharStrToUtf8((*vectNode.begin())->GetName()).c_str(), sSavePath.c_str());
+								MessageBox(hWnd, MaxTStrFromUtf8(sErrorMsg).data(), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
 							}
 						}
 					}
@@ -566,7 +566,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 						nlassert (vectNode.size()!=0);
 
 						// Save path
-						std::string sSavePath = tStrToUtf8((*vectNode.begin())->GetName());
+						std::string sSavePath = MCharStrToUtf8((*vectNode.begin())->GetName());
 
 						if (theCNelExport.SelectFileForSave (hWnd, _T("Save SWT..."), SWTFilter, sSavePath))
 						{
@@ -574,8 +574,8 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 							if (!theCNelExport.exportSWT (sSavePath, vectNode))
 							{
 								// Error message
-								std::string sErrorMsg = toString("Error exporting SWT %s in the file\n%s", tStrToUtf8((*vectNode.begin())->GetName()).c_str(), sSavePath.c_str());
-								MessageBox(hWnd, utf8ToTStr(sErrorMsg), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
+								std::string sErrorMsg = toString("Error exporting SWT %s in the file\n%s", MCharStrToUtf8((*vectNode.begin())->GetName()).c_str(), sSavePath.c_str());
+								MessageBox(hWnd, MaxTStrFromUtf8(sErrorMsg).data(), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
 							}
 						}
 					}
@@ -588,7 +588,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 					nlassert (theIP);
 					theCNelExport.init (false, true, theIP, true);
 
-					std::string sConfigFileName = tStrToUtf8(theCNelExport._Ip->GetDir(APP_PLUGCFG_DIR)) + "\\NelExportScene.cfg";
+					std::string sConfigFileName = MCharStrToUtf8(theCNelExport._Ip->GetDir(APP_PLUGCFG_DIR)) + "\\NelExportScene.cfg";
 
 					// Do a modal dialog box to choose the scene export options
 					if( DialogBox(	hInstance,
@@ -647,7 +647,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 						theCNelExport.getSelectedNode (vectNode);
 						nlassert (vectNode.size()!=0);
 
-						std::string sSavePath = tStrToUtf8((*vectNode.begin())->GetName());
+						std::string sSavePath = MCharStrToUtf8((*vectNode.begin())->GetName());
 
 						if (theCNelExport.SelectFileForSave (hWnd, _T("Save Instance group"), InstanceGroupFilter, sSavePath))
 						{
@@ -656,7 +656,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 							{
 								// Error message
 								std::string sErrorMsg = toString("Error exporting instance group %s", sSavePath.c_str());
-								MessageBox(hWnd, utf8ToTStr(sErrorMsg), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
+								MessageBox(hWnd, MaxTStrFromUtf8(sErrorMsg).data(), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
 							}
 						}
 					}
@@ -690,8 +690,8 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 							if (!theCNelExport.exportSkeleton (sSavePath, pNode, theCNelExport._Ip->GetTime()))
 							{
 								// Error message
-								std::string sErrorMsg = toString("Error exporting skeleton %s in the file\n%s", tStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
-								MessageBox(hWnd, utf8ToTStr(sErrorMsg), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
+								std::string sErrorMsg = toString("Error exporting skeleton %s in the file\n%s", MCharStrToUtf8(pNode->GetName()).c_str(), sSavePath.c_str());
+								MessageBox(hWnd, MaxTStrFromUtf8(sErrorMsg).data(), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
 							}
 						}
 					}
@@ -736,7 +736,7 @@ static INT_PTR CALLBACK CNelExportDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LP
 						}
 						catch(const std::exception &e)
 						{
-							::MessageBox(hWnd, utf8ToTStr(e.what()), _T("Error"), MB_OK | MB_ICONEXCLAMATION);
+							::MessageBoxA(hWnd, e.what(), "Error", MB_OK | MB_ICONEXCLAMATION);
 						}
 					}
 				}
@@ -820,7 +820,7 @@ void CNelExport::getSelectedNode (std::vector<INode*>& vectNode)
 void CNelExport::initOptions()
 {
 	// Initialization of theExportSceneStruct
-	std::string sConfigFileName = tStrToUtf8(theCNelExport._Ip->GetDir(APP_PLUGCFG_DIR)) + "\\NelExportScene.cfg";
+	std::string sConfigFileName = MCharStrToUtf8(theCNelExport._Ip->GetDir(APP_PLUGCFG_DIR)) + "\\NelExportScene.cfg";
 
 	// MessageBox (hWnd, sConfigFileName, "sConfigFileName", MB_OK|MB_ICONEXCLAMATION);
 	if( CFile::fileExists(sConfigFileName) )
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp
index 3be72a9bb..49e1e5ea3 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_export.cpp
@@ -329,7 +329,7 @@ bool CNelExport::exportAnim (const std::string &sPath, std::vector<INode*>& vect
 				catch (const Exception& e)
 				{
 					if (_ErrorInDialog)
-						MessageBox (NULL, utf8ToTStr(e.what()), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
+						MessageBoxA (NULL, e.what(), "NeL export", MB_OK|MB_ICONEXCLAMATION);
 					else
 						nlwarning ("ERROR : %s", e.what ());
 				}
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_filetools.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_filetools.cpp
index 11020e4fc..ea5444fca 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_filetools.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_filetools.cpp
@@ -50,8 +50,8 @@ ULONG CNelExport::SelectFileForSave(HWND Parent, const TCHAR* Title, const TCHAR
 	}
 
 	// copy path and filename to temporary buffers
-	_tcscpy_s(curdir, MAX_PATH, utf8ToTStr(path));
-	_tcscpy_s(fname, MAX_PATH, utf8ToTStr(filename));
+	_tcscpy_s(curdir, MAX_PATH, MaxTStrFromUtf8(path).data());
+	_tcscpy_s(fname, MAX_PATH, MaxTStrFromUtf8(filename).data());
 
 	OPENFILENAME ofn;
 	memset(&ofn,0,sizeof(OPENFILENAME));
@@ -69,7 +69,7 @@ ULONG CNelExport::SelectFileForSave(HWND Parent, const TCHAR* Title, const TCHAR
 	ofn.lpstrInitialDir		=	curdir;
 	BOOL r = GetSaveFileName ( &ofn );
 
-	FileName = tStrToUtf8(fname);
+	FileName = MCharStrToUtf8(fname);
 
 	return r;
 }
@@ -79,7 +79,7 @@ ULONG CNelExport::SelectFileForSave(HWND Parent, const TCHAR* Title, const TCHAR
 ULONG CNelExport::SelectDir(HWND Parent, const TCHAR* Title, std::string &Path)
 {
 	TCHAR str[MAX_PATH];
-	_tcscpy_s(str, MAX_PATH, utf8ToTStr(Path));
+	_tcscpy_s(str, MAX_PATH, MaxTStrFromUtf8(Path).data());
 
 	BROWSEINFO	bi;
 	bi.hwndOwner=Parent;
@@ -98,7 +98,7 @@ ULONG CNelExport::SelectDir(HWND Parent, const TCHAR* Title, std::string &Path)
 		return 0;
 	}
 
-	Path = tStrToUtf8(str);
+	Path = MCharStrToUtf8(str);
 
 	return 1;
 }
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
index 949395d14..efaa43238 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
@@ -90,11 +90,11 @@ class addSubLodNodeHitCallBack : public HitByNameDlgCallback
 public:
 	INodeTab	NodeTab;
 private:
-	virtual const MCHAR *dialogTitle()
+	virtual GET_OBJECT_NAME_CONST MCHAR *dialogTitle()
 	{
 		return _M("Select sub lod objects to add");
 	}
-	virtual const MCHAR *buttonText()
+	virtual GET_OBJECT_NAME_CONST MCHAR *buttonText()
 	{
 		return _M("Add");
 	}
@@ -522,27 +522,27 @@ INT_PTR CALLBACK AccelDialogCallback (
 				std::set<std::string>::iterator first(_KnownSoundGroups.begin()), last(_KnownSoundGroups.end());
 				for (; first != last; ++first)
 				{
-					SendMessage (GetDlgItem (hwndDlg, IDC_SOUND_GROUP), CB_ADDSTRING, 0, (LPARAM)utf8ToTStr(*first));
+					SendMessage (GetDlgItem (hwndDlg, IDC_SOUND_GROUP), CB_ADDSTRING, 0, (LPARAM)MaxTStrFromUtf8(*first).data());
 				}
 			}
 			// set the combo and edit box
-			if (SendMessage (GetDlgItem (hwndDlg, IDC_OCC_MODEL), CB_SELECTSTRING, -1, (LPARAM)utf8ToTStr(currentParam->OcclusionModel)) == CB_ERR)
+			if (SendMessage (GetDlgItem (hwndDlg, IDC_OCC_MODEL), CB_SELECTSTRING, -1, (LPARAM)MaxTStrFromUtf8(currentParam->OcclusionModel).data()) == CB_ERR)
 			{
 //				nlassert(false);
 			}
-			if (SendMessage (GetDlgItem (hwndDlg, IDC_OPEN_OCC_MODEL), CB_SELECTSTRING, -1, (LPARAM)utf8ToTStr(currentParam->OpenOcclusionModel)) == CB_ERR)
+			if (SendMessage (GetDlgItem (hwndDlg, IDC_OPEN_OCC_MODEL), CB_SELECTSTRING, -1, (LPARAM)MaxTStrFromUtf8(currentParam->OpenOcclusionModel).data()) == CB_ERR)
 			{
 //				nlassert(false);
 			}
-			if (SendMessage (GetDlgItem (hwndDlg, IDC_ENV_FX), CB_SELECTSTRING, -1, (LPARAM)utf8ToTStr(currentParam->EnvironmentFX)) == CB_ERR)
+			if (SendMessage (GetDlgItem (hwndDlg, IDC_ENV_FX), CB_SELECTSTRING, -1, (LPARAM)MaxTStrFromUtf8(currentParam->EnvironmentFX).data()) == CB_ERR)
 			{
 //				nlassert(false);
 			}
-			if (SendMessage (GetDlgItem (hwndDlg, IDC_SOUND_GROUP), CB_SELECTSTRING, -1, (LPARAM)utf8ToTStr(currentParam->SoundGroup)) == CB_ERR)
+			if (SendMessage (GetDlgItem (hwndDlg, IDC_SOUND_GROUP), CB_SELECTSTRING, -1, (LPARAM)MaxTStrFromUtf8(currentParam->SoundGroup).data()) == CB_ERR)
 			{
 //				nlassert(false);
 			}
-//			SendMessage(GetDlgItem(hwndDlg, IDC_SOUND_GROUP), WM_SETTEXT, 0, (LPARAM)utf8ToTStr(currentParam->SoundGroup));
+//			SendMessage(GetDlgItem(hwndDlg, IDC_SOUND_GROUP), WM_SETTEXT, 0, (LPARAM)MaxTStrFromUtf8(currentParam->SoundGroup).data());
 
 			bool accelerator = (currentParam->AcceleratorType != -1);
 			CheckRadioButton (hwndDlg, IDC_RADIOACCELNO, IDC_RADIOACCELCLUSTER, accelerator?(IDC_RADIOACCELNO+(currentParam->AcceleratorType&NEL3D_APPDATA_ACCEL_TYPE)):0);
@@ -583,14 +583,14 @@ INT_PTR CALLBACK AccelDialogCallback (
 							// get the strings params
 							TCHAR tmp[256];
 							SendMessage (GetDlgItem(hwndDlg, IDC_OCC_MODEL), WM_GETTEXT, 256, (LPARAM)tmp);
-							currentParam->OcclusionModel = tStrToUtf8(tmp);
+							currentParam->OcclusionModel = MCharStrToUtf8(tmp);
 							SendMessage (GetDlgItem(hwndDlg, IDC_OPEN_OCC_MODEL), WM_GETTEXT, 256, (LPARAM)tmp);
-							currentParam->OpenOcclusionModel = tStrToUtf8(tmp);
+							currentParam->OpenOcclusionModel = MCharStrToUtf8(tmp);
 							SendMessage (GetDlgItem(hwndDlg, IDC_SOUND_GROUP), WM_GETTEXT, 256, (LPARAM)tmp);
-							currentParam->SoundGroup = tStrToUtf8(tmp);
+							currentParam->SoundGroup = MCharStrToUtf8(tmp);
 							_KnownSoundGroups.insert(currentParam->SoundGroup);
 							SendMessage (GetDlgItem(hwndDlg, IDC_ENV_FX), WM_GETTEXT, 256, (LPARAM)tmp);
-							currentParam->EnvironmentFX = tStrToUtf8(tmp);
+							currentParam->EnvironmentFX = MCharStrToUtf8(tmp);
 
 							// Quit
 							EndDialog(hwndDlg, IDOK);
@@ -653,9 +653,9 @@ INT_PTR CALLBACK MRMDialogCallback (
 			currentParam=(CLodDialogBoxParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 
 			// Window text
-			std::string winName= tStrToUtf8((*(currentParam->ListNode->begin()))->GetName());
+			std::string winName= MCharStrToUtf8((*(currentParam->ListNode->begin()))->GetName());
 			winName="Node properties ("+winName+((currentParam->ListNode->size()>1)?" ...)":")");
-			SetWindowText (hwndDlg, utf8ToTStr(winName));
+			SetWindowText (hwndDlg, MaxTStrFromUtf8(winName).data());
 
 			// Set default state
 			SendMessage (GetDlgItem (hwndDlg, IDC_BLEND_IN), BM_SETCHECK, currentParam->BlendIn, 0);
@@ -669,8 +669,8 @@ INT_PTR CALLBACK MRMDialogCallback (
 			EnableWindow (GetDlgItem (hwndDlg, IDC_UP), currentParam->ListActived);
 			EnableWindow (GetDlgItem (hwndDlg, IDC_DOWN), currentParam->ListActived);
 
-			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_MAX), utf8ToTStr(currentParam->DistMax));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_BLEND_LENGTH), utf8ToTStr(currentParam->BlendLength));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_MAX), MaxTStrFromUtf8(currentParam->DistMax).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_BLEND_LENGTH), MaxTStrFromUtf8(currentParam->BlendLength).data());
 
 			SendMessage (GetDlgItem (hwndDlg, IDC_ACTIVE_MRM), BM_SETCHECK, currentParam->MRM, 0);
 			CoarseStateChanged (hwndDlg);
@@ -678,12 +678,12 @@ INT_PTR CALLBACK MRMDialogCallback (
 			if (currentParam->SkinReduction!=-1)
 				CheckRadioButton (hwndDlg, IDC_SKIN_REDUCTION_MIN, IDC_SKIN_REDUCTION_BEST, IDC_SKIN_REDUCTION_MIN+currentParam->SkinReduction);
 
-			SetWindowText (GetDlgItem (hwndDlg, IDC_NB_LOD), utf8ToTStr(currentParam->NbLod));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_DIVISOR), utf8ToTStr(currentParam->Divisor));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_FINEST), utf8ToTStr(currentParam->DistanceFinest));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_MIDDLE), utf8ToTStr(currentParam->DistanceMiddle));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_COARSEST), utf8ToTStr(currentParam->DistanceCoarsest));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_BONE_LOD_DISTANCE), utf8ToTStr(currentParam->BoneLodDistance));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_NB_LOD), MaxTStrFromUtf8(currentParam->NbLod).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_DIVISOR), MaxTStrFromUtf8(currentParam->Divisor).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_FINEST), MaxTStrFromUtf8(currentParam->DistanceFinest).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_MIDDLE), MaxTStrFromUtf8(currentParam->DistanceMiddle).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_DIST_COARSEST), MaxTStrFromUtf8(currentParam->DistanceCoarsest).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_BONE_LOD_DISTANCE), MaxTStrFromUtf8(currentParam->BoneLodDistance).data());
 
 			// Iterate list
 			HWND hwndList=GetDlgItem (hwndDlg, IDC_LIST1);
@@ -719,9 +719,9 @@ INT_PTR CALLBACK MRMDialogCallback (
 
 							TCHAR tmp[512];
 							GetWindowText (GetDlgItem (hwndDlg, IDC_DIST_MAX), tmp, 512);
-							currentParam->DistMax = tStrToUtf8(tmp);
+							currentParam->DistMax = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_BLEND_LENGTH), tmp, 512);
-							currentParam->BlendLength = tStrToUtf8(tmp);
+							currentParam->BlendLength = MCharStrToUtf8(tmp);
 
 							currentParam->MRM=SendMessage (GetDlgItem (hwndDlg, IDC_ACTIVE_MRM), BM_GETCHECK, 0, 0);
 
@@ -734,17 +734,17 @@ INT_PTR CALLBACK MRMDialogCallback (
 								currentParam->SkinReduction=2;
 
 							GetWindowText (GetDlgItem (hwndDlg, IDC_NB_LOD), tmp, 512);
-							currentParam->NbLod = tStrToUtf8(tmp);
+							currentParam->NbLod = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_DIVISOR), tmp, 512);
-							currentParam->Divisor = tStrToUtf8(tmp);
+							currentParam->Divisor = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_DIST_FINEST), tmp, 512);
-							currentParam->DistanceFinest = tStrToUtf8(tmp);
+							currentParam->DistanceFinest = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_DIST_MIDDLE), tmp, 512);
-							currentParam->DistanceMiddle = tStrToUtf8(tmp);
+							currentParam->DistanceMiddle = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_DIST_COARSEST), tmp, 512);
-							currentParam->DistanceCoarsest = tStrToUtf8(tmp);
+							currentParam->DistanceCoarsest = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_BONE_LOD_DISTANCE), tmp, 512);
-							currentParam->BoneLodDistance = tStrToUtf8(tmp);
+							currentParam->BoneLodDistance = MCharStrToUtf8(tmp);
 
 							// Iterate list
 							HWND hwndList=GetDlgItem (hwndDlg, IDC_LIST1);
@@ -758,7 +758,7 @@ INT_PTR CALLBACK MRMDialogCallback (
 								SendMessage (hwndList, LB_GETTEXT, item, (LPARAM) tmp);
 
 								// Push it back
-								currentParam->ListLodName.push_back (tStrToUtf8(tmp));
+								currentParam->ListLodName.push_back (MCharStrToUtf8(tmp));
 							}
 
 							// default LodCharacter
@@ -920,8 +920,8 @@ INT_PTR CALLBACK InstanceDialogCallback (
 			LONG_PTR res = SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
 			currentParam=(CLodDialogBoxParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_GROUP_SHAPE), utf8ToTStr(currentParam->InstanceShape));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_NAME), utf8ToTStr(currentParam->InstanceName));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_GROUP_SHAPE), MaxTStrFromUtf8(currentParam->InstanceShape).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_NAME), MaxTStrFromUtf8(currentParam->InstanceName).data());
 
 			SendMessage (GetDlgItem (hwndDlg, IDC_DONT_ADD_TO_SCENE), BM_SETCHECK, currentParam->DontAddToScene, 0);
 
@@ -930,7 +930,7 @@ INT_PTR CALLBACK InstanceDialogCallback (
 
 			SendMessage (GetDlgItem (hwndDlg, IDC_CHECK_COLLISION), BM_SETCHECK, currentParam->Collision, 0);
 			SendMessage (GetDlgItem (hwndDlg, IDC_CHECK_COLLISION_EXTERIOR), BM_SETCHECK, currentParam->CollisionExterior, 0);
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_GROUP_NAME), utf8ToTStr(currentParam->InstanceGroupName));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_GROUP_NAME), MaxTStrFromUtf8(currentParam->InstanceGroupName).data());
 
 			bool colOk = currentParam->CollisionMeshGeneration>=0 && currentParam->CollisionMeshGeneration<4;
 			CheckRadioButton (hwndDlg, IDC_CAMERA_COL_RADIO1, IDC_CAMERA_COL_RADIO4, colOk?(IDC_CAMERA_COL_RADIO1+(currentParam->CollisionMeshGeneration)):0);
@@ -952,14 +952,14 @@ INT_PTR CALLBACK InstanceDialogCallback (
 						{
 							TCHAR tmp[512];
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_GROUP_SHAPE), tmp, 512);
-							currentParam->InstanceShape = tStrToUtf8(tmp);
+							currentParam->InstanceShape = MCharStrToUtf8(tmp);
 
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_NAME), tmp, 512);
-							currentParam->InstanceName = tStrToUtf8(tmp);
+							currentParam->InstanceName = MCharStrToUtf8(tmp);
 
 							currentParam->DontAddToScene=SendMessage (GetDlgItem (hwndDlg, IDC_DONT_ADD_TO_SCENE), BM_GETCHECK, 0, 0);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INSTANCE_GROUP_NAME), tmp, 512);
-							currentParam->InstanceGroupName = tStrToUtf8(tmp);
+							currentParam->InstanceGroupName = MCharStrToUtf8(tmp);
 
 							currentParam->DontExport=SendMessage (GetDlgItem (hwndDlg, IDC_DONT_EXPORT), BM_GETCHECK, 0, 0);
 
@@ -1036,9 +1036,9 @@ INT_PTR CALLBACK LightmapDialogCallback (
 			LONG_PTR res = SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
 			currentParam=(CLodDialogBoxParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_LUMELSIZEMUL), utf8ToTStr(currentParam->LumelSizeMul));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_SOFTSHADOW_RADIUS), utf8ToTStr(currentParam->SoftShadowRadius));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_SOFTSHADOW_CONELENGTH), utf8ToTStr(currentParam->SoftShadowConeLength));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_LUMELSIZEMUL), MaxTStrFromUtf8(currentParam->LumelSizeMul).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_SOFTSHADOW_RADIUS), MaxTStrFromUtf8(currentParam->SoftShadowRadius).data());
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_SOFTSHADOW_CONELENGTH), MaxTStrFromUtf8(currentParam->SoftShadowConeLength).data());
 
 			// Lighting
 			SendMessage (GetDlgItem (hwndDlg, IDC_EXPORT_REALTIME_LIGHT), BM_SETCHECK, currentParam->ExportRealTimeLight, 0);
@@ -1048,7 +1048,7 @@ INT_PTR CALLBACK LightmapDialogCallback (
 			SendMessage (GetDlgItem (hwndDlg, IDC_USE_LIGHT_LOCAL_ATTENUATION), BM_SETCHECK, currentParam->UseLightingLocalAttenuation, 0);
 			SendMessage (GetDlgItem (hwndDlg, IDC_LIGHT_DONT_CAST_SHADOW_INTERIOR), BM_SETCHECK, currentParam->LightDontCastShadowInterior, 0);
 			SendMessage (GetDlgItem (hwndDlg, IDC_LIGHT_DONT_CAST_SHADOW_EXTERIOR), BM_SETCHECK, currentParam->LightDontCastShadowExterior, 0);
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EXPORT_LIGHTMAP_NAME), utf8ToTStr(currentParam->ExportLightMapName));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EXPORT_LIGHTMAP_NAME), MaxTStrFromUtf8(currentParam->ExportLightMapName).data());
 			SendMessage (GetDlgItem (hwndDlg, IDC_REALTIME_LIGHT_AMBIENT_ADD_SUN), BM_SETCHECK, currentParam->RealTimeAmbientLightAddSun, 0);
 
 			// Set enable disable
@@ -1075,11 +1075,11 @@ INT_PTR CALLBACK LightmapDialogCallback (
 							// Set default state
 							TCHAR tmp[512];
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_LUMELSIZEMUL), tmp, 512);
-							currentParam->LumelSizeMul = tStrToUtf8(tmp);
+							currentParam->LumelSizeMul = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_SOFTSHADOW_RADIUS), tmp, 512);
-							currentParam->SoftShadowRadius = tStrToUtf8(tmp);
+							currentParam->SoftShadowRadius = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_SOFTSHADOW_CONELENGTH), tmp, 512);
-							currentParam->SoftShadowConeLength = tStrToUtf8(tmp);
+							currentParam->SoftShadowConeLength = MCharStrToUtf8(tmp);
 
 							// RealTime light
 							currentParam->ExportRealTimeLight = SendMessage (GetDlgItem (hwndDlg, IDC_EXPORT_REALTIME_LIGHT), BM_GETCHECK, 0, 0);
@@ -1090,7 +1090,7 @@ INT_PTR CALLBACK LightmapDialogCallback (
 							currentParam->LightDontCastShadowExterior = SendMessage (GetDlgItem (hwndDlg, IDC_LIGHT_DONT_CAST_SHADOW_EXTERIOR), BM_GETCHECK, 0, 0);
 							currentParam->ExportLightMapAnimated = SendMessage (GetDlgItem (hwndDlg, IDC_EXPORT_LIGHTMAP_ANIMATED), BM_GETCHECK, 0, 0);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EXPORT_LIGHTMAP_NAME), tmp, 512);
-							currentParam->ExportLightMapName = tStrToUtf8(tmp);
+							currentParam->ExportLightMapName = MCharStrToUtf8(tmp);
 							currentParam->RealTimeAmbientLightAddSun= SendMessage (GetDlgItem (hwndDlg, IDC_REALTIME_LIGHT_AMBIENT_ADD_SUN), BM_GETCHECK, 0, 0);
 
 							// Get the acceleration type
@@ -1679,7 +1679,7 @@ INT_PTR CALLBACK VegetableDialogCallback (
 
 			CheckRadioButton(hwndDlg, IDC_CENTER_NULL, IDC_CENTER_Z, IDC_CENTER_NULL+currentParam->VegetableBendCenter);
 
-			SetWindowText (GetDlgItem (hwndDlg, IDC_VEGETABLE_BEND_FACTOR), utf8ToTStr(currentParam->VegetableBendFactor));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_VEGETABLE_BEND_FACTOR), MaxTStrFromUtf8(currentParam->VegetableBendFactor).data());
 
 			VegetableStateChanged (hwndDlg);
 		}
@@ -1734,7 +1734,7 @@ INT_PTR CALLBACK VegetableDialogCallback (
 
 							TCHAR tmp[512];
 							GetWindowText (GetDlgItem (hwndDlg, IDC_VEGETABLE_BEND_FACTOR), tmp, 512);
-							currentParam->VegetableBendFactor = tStrToUtf8(tmp);
+							currentParam->VegetableBendFactor = MCharStrToUtf8(tmp);
 						}
 					break;
 					case IDC_VEGETABLE:
@@ -2290,34 +2290,34 @@ INT_PTR CALLBACK MiscDialogCallback (
 
 			// Ligoscape
 			SendMessage (GetDlgItem (hwndDlg, IDC_LIGO_SYMMETRY), BM_SETCHECK, currentParam->LigoSymmetry, 0);
-			SetWindowText (GetDlgItem (hwndDlg, IDC_LIGO_ROTATE), utf8ToTStr(currentParam->LigoRotate));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_LIGO_ROTATE), MaxTStrFromUtf8(currentParam->LigoRotate).data());
 
 			// SWT
 			SendMessage (GetDlgItem (hwndDlg, IDC_SWT), BM_SETCHECK, currentParam->SWT, 0);
-			SetWindowText (GetDlgItem (hwndDlg, IDC_SWT_WEIGHT), utf8ToTStr(currentParam->SWTWeight));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_SWT_WEIGHT), MaxTStrFromUtf8(currentParam->SWTWeight).data());
 
 			// Radial normals
 			for (uint smoothGroup=0; smoothGroup<NEL3D_RADIAL_NORMAL_COUNT; smoothGroup++)
-				SetWindowText (GetDlgItem (hwndDlg, IDC_RADIAL_NORMAL_29+smoothGroup), utf8ToTStr(currentParam->RadialNormals[smoothGroup]));
+				SetWindowText (GetDlgItem (hwndDlg, IDC_RADIAL_NORMAL_29+smoothGroup), MaxTStrFromUtf8(currentParam->RadialNormals[smoothGroup]).data());
 
 			// Mesh interfaces
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INTERFACE_FILE), utf8ToTStr(currentParam->InterfaceFileName));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INTERFACE_FILE), MaxTStrFromUtf8(currentParam->InterfaceFileName).data());
 			SetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INTERFACE_THRESHOLD),
-							currentParam->InterfaceThreshold != -1.f ? utf8ToTStr(toStringMax(currentParam->InterfaceThreshold))
+							currentParam->InterfaceThreshold != -1.f ? MaxTStrFromUtf8(toStringMax(currentParam->InterfaceThreshold)).data()
 																	 : _T("")
 						  );
 			SendMessage(GetDlgItem(hwndDlg, IDC_GET_INTERFACE_NORMAL_FROM_SCENE_OBJECTS), BM_SETCHECK, currentParam->GetInterfaceNormalsFromSceneObjects, 0);
 
 			// Skeleton Scale
 			SendMessage( GetDlgItem(hwndDlg, IDC_EXPORT_BONE_SCALE), BM_SETCHECK, currentParam->ExportBoneScale, 0);
-			SetWindowText (GetDlgItem (hwndDlg, IDC_EXPORT_BONE_SCALE_NAME_EXT), utf8ToTStr(currentParam->ExportBoneScaleNameExt));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_EXPORT_BONE_SCALE_NAME_EXT), MaxTStrFromUtf8(currentParam->ExportBoneScaleNameExt).data());
 
 			// Remanence
 			SendMessage (GetDlgItem (hwndDlg, IDC_USE_REMANENCE), BM_SETCHECK, currentParam->UseRemanence, 0);
 			SendMessage (GetDlgItem (hwndDlg, IDC_REMANENCE_SHIFTING_TEXTURE), BM_SETCHECK, currentParam->RemanenceShiftingTexture, 0);
-			SetWindowText (GetDlgItem (hwndDlg, IDC_REMANENCE_SLICE_NUMBER), currentParam->RemanenceSliceNumber != - 1 ? utf8ToTStr(toStringMax(currentParam->RemanenceSliceNumber)) : _T(""));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_REMANENCE_SAMPLING_PERIOD), currentParam->RemanenceSamplingPeriod != -1 ? utf8ToTStr(toStringMax(currentParam->RemanenceSamplingPeriod)) : _T(""));
-			SetWindowText (GetDlgItem (hwndDlg, IDC_REMANENCE_ROLLUP_RATIO), currentParam->RemanenceRollupRatio != -1 ? utf8ToTStr(toStringMax(currentParam->RemanenceRollupRatio)) : _T(""));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_REMANENCE_SLICE_NUMBER), currentParam->RemanenceSliceNumber != - 1 ? MaxTStrFromUtf8(toStringMax(currentParam->RemanenceSliceNumber)).data() : _T(""));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_REMANENCE_SAMPLING_PERIOD), currentParam->RemanenceSamplingPeriod != -1 ? MaxTStrFromUtf8(toStringMax(currentParam->RemanenceSamplingPeriod)).data() : _T(""));
+			SetWindowText (GetDlgItem (hwndDlg, IDC_REMANENCE_ROLLUP_RATIO), currentParam->RemanenceRollupRatio != -1 ? MaxTStrFromUtf8(toStringMax(currentParam->RemanenceRollupRatio)).data() : _T(""));
 		}
 		break;
 
@@ -2338,24 +2338,24 @@ INT_PTR CALLBACK MiscDialogCallback (
 							currentParam->LigoSymmetry = SendMessage (GetDlgItem (hwndDlg, IDC_LIGO_SYMMETRY), BM_GETCHECK, 0, 0);
 							TCHAR tmp[512];
 							GetWindowText (GetDlgItem (hwndDlg, IDC_LIGO_ROTATE), tmp, 512);
-							currentParam->LigoRotate = tStrToUtf8(tmp);
+							currentParam->LigoRotate = MCharStrToUtf8(tmp);
 
 							// SWT
 							currentParam->SWT = SendMessage (GetDlgItem (hwndDlg, IDC_SWT), BM_GETCHECK, 0, 0);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_SWT_WEIGHT), tmp, 512);
-							currentParam->SWTWeight = tStrToUtf8(tmp);
+							currentParam->SWTWeight = MCharStrToUtf8(tmp);
 
 							// Radial normals
 							for (uint smoothGroup=0; smoothGroup<NEL3D_RADIAL_NORMAL_COUNT; smoothGroup++)
 							{
 								HWND edit = GetDlgItem (hwndDlg, IDC_RADIAL_NORMAL_29+smoothGroup);
 								GetWindowText (edit, tmp, 512);
-								currentParam->RadialNormals[smoothGroup] = tStrToUtf8(tmp);
+								currentParam->RadialNormals[smoothGroup] = MCharStrToUtf8(tmp);
 							}
 
 							// mesh interfaces
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INTERFACE_FILE), tmp, 512);
-							currentParam->InterfaceFileName = tStrToUtf8(tmp);
+							currentParam->InterfaceFileName = MCharStrToUtf8(tmp);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EDIT_INTERFACE_THRESHOLD), tmp, 512);
 							if (_tcslen(tmp) != 0)
 								currentParam->InterfaceThreshold = toFloatMax(tmp);
@@ -2365,7 +2365,7 @@ INT_PTR CALLBACK MiscDialogCallback (
 							// Skeleton Scale
 							currentParam->ExportBoneScale= SendMessage( GetDlgItem(hwndDlg, IDC_EXPORT_BONE_SCALE), BM_GETCHECK, 0, 0);
 							GetWindowText (GetDlgItem (hwndDlg, IDC_EXPORT_BONE_SCALE_NAME_EXT), tmp, 512);
-							currentParam->ExportBoneScaleNameExt = tStrToUtf8(tmp);
+							currentParam->ExportBoneScaleNameExt = MCharStrToUtf8(tmp);
 
 							// remanence
 							currentParam->UseRemanence = SendMessage (GetDlgItem (hwndDlg, IDC_USE_REMANENCE), BM_GETCHECK, 0, 0);
@@ -2374,7 +2374,7 @@ INT_PTR CALLBACK MiscDialogCallback (
 							GetWindowText (GetDlgItem (hwndDlg, IDC_REMANENCE_SLICE_NUMBER), tmp, 512);
 
 							uint rsn;
-							if (NLMISC::fromString(tStrToUtf8(tmp), rsn))
+							if (NLMISC::fromString(MCharStrToUtf8(tmp), rsn))
 							{
 								currentParam->RemanenceSliceNumber = rsn;
 							}
@@ -2489,12 +2489,12 @@ INT_PTR CALLBACK LodDialogCallback (
 		{
 			// Param pointers
 			LONG_PTR res = SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
-			currentParam=(CLodDialogBoxParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+			currentParam = (CLodDialogBoxParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 
 			// Window text
-			std::string winName = tStrToUtf8((*(currentParam->ListNode->begin()))->GetName());
-			winName="Node properties ("+winName+((currentParam->ListNode->size()>1)?" ...)":")");
-			SetWindowText (hwndDlg, utf8ToTStr(winName));
+			TSTR winName = (*(currentParam->ListNode->begin()))->GetName();
+			winName = TSTR("Node properties (") + winName + ((currentParam->ListNode->size() > 1) ? _M(" ...)") : _M(")"));
+			SetWindowText(hwndDlg, winName.data());
 
 			// Move dialog
 			RECT windowRect, desktopRect;
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_scene.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_scene.cpp
index b50903324..9a57dfeeb 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_scene.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_scene.cpp
@@ -59,7 +59,7 @@ bool CNelExport::exportInstanceGroup(string filename, vector<INode*>& vectNode)
 			catch (const Exception &c)
 			{
 				// Cannot save the file
-				MessageBox (NULL, utf8ToTStr(c.what()), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(NULL, MaxTStrFromUtf8(c.what()).data(), _T("NeL export"), MB_OK|MB_ICONEXCLAMATION);
 				return false;
 			}
 		}
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp
index dfdbdec08..d28cb48b0 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_script.cpp
@@ -91,7 +91,7 @@ Value* export_shape_cf (Value** arg_list, int count)
 	theCNelExport.init (false, false, ip, true);
 
 	// Export path 
-	std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+	std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Ok ?
 	Boolean *ret=&false_value;
@@ -154,12 +154,12 @@ Value* export_shape_ex_cf (Value** arg_list, int count)
 	nlassert(node->GetName());
 
 	// Export path 
-	std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+	std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Ex argu
 	theExportSceneStruct.bShadow = arg_list[2]->to_bool()!=FALSE;
 	theExportSceneStruct.bExportLighting = arg_list[3]->to_bool()!=FALSE;
-	theExportSceneStruct.sExportLighting = tStrToUtf8(arg_list[4]->to_string());
+	theExportSceneStruct.sExportLighting = MCharStrToUtf8(arg_list[4]->to_string());
 	theExportSceneStruct.nExportLighting = arg_list[5]->to_int();
 	theExportSceneStruct.rLumelSize = arg_list[6]->to_float();
 	theExportSceneStruct.nOverSampling = arg_list[7]->to_int();
@@ -220,7 +220,7 @@ Value* export_skeleton_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// Export path 
-	std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+	std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Ok ?
 	Boolean *ret=&false_value;
@@ -260,7 +260,7 @@ Value* export_animation_cf (Value** arg_list, int count)
 	theCNelExport.init (false, false, ip, true);
 
 	// Export path 
-	std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+	std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Get time
 	TimeValue time=MAXScript_interface->GetTime();
@@ -298,7 +298,7 @@ Value* export_animation_cf (Value** arg_list, int count)
 			else
 			{
 				// Error message
-				mprintf (_M("Error exporting animation %s in the file\n%s\n"), (*vectNode.begin())->GetName(), utf8ToTStr(sPath));
+				mprintf(_M("Error exporting animation %s in the file\n%s\n"), (*vectNode.begin())->GetName(), MaxTStrFromUtf8(sPath).data());
 			}
 		}
 	}
@@ -352,7 +352,7 @@ Value* export_ig_cf (Value** arg_list, int count)
 					vect.push_back (array->get (i+1)->to_node());
 					
 				// Export path 
-				std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+				std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 				// Export
 				if (theCNelExport.exportInstanceGroup (sPath, vect))
@@ -411,7 +411,7 @@ Value* export_skeleton_weight_cf (Value** arg_list, int count)
 					vect.push_back (array->get (i+1)->to_node());
 					
 				// Export path 
-				std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+				std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 				// Export
 				if (theCNelExport.exportSWT (sPath, vect))
@@ -462,8 +462,8 @@ Value* test_file_date_cf (Value** arg_list, int count)
 	// Make sure we have the correct number of arguments (2)
 	check_arg_count(view_shape, 2, count);
 
-	type_check (arg_list[0], String, _M("NeLTestFileDate [DestFilename] [SrcFilename]"));
-	type_check (arg_list[1], String, _M("NeLTestFileDate [DestFilename] [SrcFilename]"));
+	type_check(arg_list[0], String, _M("NeLTestFileDate [DestFilename] [SrcFilename]"));
+	type_check(arg_list[1], String, _M("NeLTestFileDate [DestFilename] [SrcFilename]"));
 
 	// Get a good interface pointer
 	Interface *ip = MAXScript_interface;
@@ -471,11 +471,11 @@ Value* test_file_date_cf (Value** arg_list, int count)
 	theCNelExport.init (false, false, ip, true);
 
 	// The 2 filenames
-	string file0 = tStrToUtf8(arg_list[0]->to_string());
-	string file1 = tStrToUtf8(arg_list[1]->to_string());
+	WStr file0 = arg_list[0]->to_string();
+	WStr file1 = arg_list[1]->to_string();
 
 	// Open it
-	FILE *file=nlfopen (file0.c_str(), "r");
+	FILE *file= nlfopen(ucstring((const ucchar *)file0.data()).toUtf8().c_str(), "r");
 	if (file == NULL)
 		return &true_value;
 	
@@ -486,10 +486,10 @@ Value* test_file_date_cf (Value** arg_list, int count)
 	Value *ret = &undefined;
 
 	// Create first file
-	HANDLE h0 = CreateFile (utf8ToTStr(file0), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	HANDLE h0 = CreateFileW((LPCWSTR)file0.data(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 	if (h0!=INVALID_HANDLE_VALUE)
 	{
-		HANDLE h1 = CreateFile (utf8ToTStr(file1), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+		HANDLE h1 = CreateFileW((LPCWSTR)file1.data(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 		if (h1!=INVALID_HANDLE_VALUE)
 		{
 			// Get file time
@@ -536,7 +536,7 @@ Value* export_vegetable_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// Export path 
-	std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+	std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Message in dialog
 	bool dialogMessage = arg_list[2]->to_bool() != FALSE;
@@ -615,7 +615,7 @@ Value* export_collision_cf (Value** arg_list, int count)
 	theCNelExport.init (false, false, ip, true);
 
 	// Export path 
-	string sPath = tStrToUtf8(arg_list[1]->to_string());
+	string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Get time
 	TimeValue time = MAXScript_interface->GetTime();
@@ -674,7 +674,7 @@ Value* export_pacs_primitives_cf (Value** arg_list, int count)
 	theCNelExport.init (false, false, ip, true);
 
 	// Export path 
-	string sPath = tStrToUtf8(arg_list[1]->to_string());
+	string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Get time
 	TimeValue time = MAXScript_interface->GetTime();
@@ -733,7 +733,7 @@ Value* export_lod_character_cf (Value** arg_list, int count)
 	nlassert (node);
 
 	// Export path 
-	std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+	std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 	// Message in dialog
 	bool dialogMessage = arg_list[2]->to_bool() != FALSE;
@@ -879,18 +879,18 @@ Value* get_file_modification_date_cf (Value** arg_list, int count)
 	type_check (arg_list[0], String, message);
 	
 	// get the node
-	string sPath = tStrToUtf8(arg_list[0]->to_string());
+	WStr sPath = arg_list[0]->to_string();
 
 	// get vertices indices
 	string result;
-	HANDLE file = CreateFile (utf8ToTStr(sPath), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	HANDLE file = CreateFileW((LPCWSTR)sPath.data(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 	if (file)
 	{
 		FILETIME lastWriteTime;
 		if (GetFileTime(file, NULL, NULL, &lastWriteTime))
 		{
 			char number[512];
-			sprintf (number, "%08x%08x", lastWriteTime.dwHighDateTime, lastWriteTime.dwLowDateTime);
+			sprintf(number, "%08x%08x", lastWriteTime.dwHighDateTime, lastWriteTime.dwLowDateTime);
 			result = number;
 		}
 		CloseHandle (file);
@@ -899,7 +899,7 @@ Value* get_file_modification_date_cf (Value** arg_list, int count)
 	if (result.empty())
 		return &undefined;
 	else
-		return new String(utf8ToTStr(result));
+		return new String(MaxTStrFromUtf8(result));
 }
 
 // ***************************************************************************
@@ -914,24 +914,24 @@ Value* set_file_modification_date_cf (Value** arg_list, int count)
 	MCHAR *message = _M("bool NeLSetFileModificationDate [filename] [date] - If an error occurred, returns false.");
 	
 	//type_check
-	type_check (arg_list[0], String, message);
-	type_check (arg_list[1], String, message);
+	type_check(arg_list[0], String, message);
+	type_check(arg_list[1], String, message);
 	
 	// get the node
-	string sPath = tStrToUtf8(arg_list[0]->to_string());
-	string sDate = tStrToUtf8(arg_list[1]->to_string());
+	WStr sPath = arg_list[0]->to_string();
+	WStr sDate = arg_list[1]->to_string();
 
 	// get vertices indices
 	string result;
-	HANDLE file = CreateFile (utf8ToTStr(sPath), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	HANDLE file = CreateFileW(sPath.data(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 	if (file)
 	{
 		FILETIME lastWriteTime;
-		if (sscanf (sDate.c_str(), "%08x%08x", &lastWriteTime.dwHighDateTime, &lastWriteTime.dwLowDateTime) == 2)
+		if (swscanf(sDate.data(), L"%08x%08x", &lastWriteTime.dwHighDateTime, &lastWriteTime.dwLowDateTime) == 2)
 		{
 			if (SetFileTime(file, NULL, NULL, &lastWriteTime))
 			{
-				CloseHandle (file);
+				CloseHandle(file);
 				return &true_value;
 			}
 		}
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_swt.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_swt.cpp
index c466b7055..e9ca83451 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_swt.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_swt.cpp
@@ -55,15 +55,15 @@ bool CNelExport::exportSWT(const std::string &sPath, std::vector<INode*>& vectNo
 
 			// Store them in the temporary list
 			aSWNodes.resize(nNumNode+3);
-			aSWNodes[nNumNode].Name = tStrToUtf8(pNode->GetName());
+			aSWNodes[nNumNode].Name = MCharStrToUtf8(pNode->GetName());
 			aSWNodes[nNumNode].Name += std::string (".")+ITransformable::getRotQuatValueName();
 			aSWNodes[nNumNode].Weight = rRotValue;
 			++nNumNode;
-			aSWNodes[nNumNode].Name = tStrToUtf8(pNode->GetName());
+			aSWNodes[nNumNode].Name = MCharStrToUtf8(pNode->GetName());
 			aSWNodes[nNumNode].Name += std::string (".")+ITransformable::getPosValueName ();
 			aSWNodes[nNumNode].Weight = rPosValue;
 			++nNumNode;
-			aSWNodes[nNumNode].Name = tStrToUtf8(pNode->GetName());
+			aSWNodes[nNumNode].Name = MCharStrToUtf8(pNode->GetName());
 			aSWNodes[nNumNode].Name += std::string (".")+ITransformable::getScaleValueName();
 			aSWNodes[nNumNode].Weight = rScaleValue;
 			++nNumNode;
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_view.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_view.cpp
index adfba5a98..431155929 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_view.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_view.cpp
@@ -113,7 +113,7 @@ void regsiterOVPath ()
 	int res = GetModuleFileName(hModule, sModulePath, 256);
 	if (!res) { ::MessageBox(NULL, _T("'res' failed at '") __FUNCTION__ _T("' in file '") __FILE__ _T(" on line ") NL_MACRO_TO_STR(__LINE__), _T("NeL Export"), MB_OK | MB_ICONERROR); return; }
 
-	std::string modulePath = NLMISC::CFile::getPath(tStrToUtf8(sModulePath)) + "object_viewer.cfg";
+	std::string modulePath = NLMISC::CFile::getPath(MCharStrToUtf8(sModulePath)) + "object_viewer.cfg";
 
 	// Load the config file
 	CConfigFile cf;
@@ -300,7 +300,7 @@ void CNelExport::viewMesh (TimeValue time)
 							_ExportNel->buildSkeletonShape (*skelShape, *skeletonRoot, &(iteSkeleton->second), mapId, time);
 
 							// Add the shape in the view
-							uint instance = view->addSkel (skelShape, tStrToUtf8(skeletonRoot->GetName()));
+							uint instance = view->addSkel (skelShape, MCharStrToUtf8(skeletonRoot->GetName()));
 
 							// Add tracks
 							CAnimation *anim=new CAnimation;
@@ -365,7 +365,7 @@ void CNelExport::viewMesh (TimeValue time)
 			INode* pNode=_Ip->GetSelNode (nNode);
 
 			string sTmp = "Object Name: ";
-			sTmp += tStrToUtf8(pNode->GetName());
+			sTmp += MCharStrToUtf8(pNode->GetName());
 			ProgBar.setLine (0, sTmp);
 			sTmp.clear();
 			for (uint32 i = 1; i < 10; ++i) 
@@ -410,7 +410,7 @@ void CNelExport::viewMesh (TimeValue time)
 						if (pShape)
 						{
 							// Add the shape in the view
-							uint instance = view->addMesh (pShape, tStrToUtf8(pNode->GetName()).c_str(), iteSkelShape->second.SkeletonInstance);
+							uint instance = view->addMesh (pShape, MCharStrToUtf8(pNode->GetName()), iteSkelShape->second.SkeletonInstance);
 
 							// Add tracks
 							CAnimation *anim=new CAnimation;
diff --git a/code/nel/tools/3d/plugin_max/nel_export/progress.cpp b/code/nel/tools/3d/plugin_max/nel_export/progress.cpp
index 17b3fab2a..495c4687d 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/progress.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/progress.cpp
@@ -70,7 +70,7 @@ INT_PTR CALLBACK CalculatingDialogCallback (
 			string all;
 			for (uint32 i = 0; i < 14; ++i)
 				all += pClass->sInfoProgress[i] + "\n";
-			SendMessage (GetDlgItem (hwndDlg, IDC_STATICINFO), WM_SETTEXT, 0, (LPARAM)utf8ToTStr(all));
+			SendMessage (GetDlgItem (hwndDlg, IDC_STATICINFO), WM_SETTEXT, 0, (LPARAM)MaxTStrFromUtf8(all).data());
 		}
 		break;
 
diff --git a/code/nel/tools/3d/plugin_max/nel_export/std_afx.cpp b/code/nel/tools/3d/plugin_max/nel_export/std_afx.cpp
index 6d0ee506b..424138cda 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/std_afx.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/std_afx.cpp
@@ -14,6 +14,7 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-
 #include "std_afx.h"
 
+void nlmax_nel_export_std_afx_dummy() { }
+
diff --git a/code/nel/tools/3d/plugin_max/nel_export/std_afx.h b/code/nel/tools/3d/plugin_max/nel_export/std_afx.h
index ba7b4b4c0..27dd8372a 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/std_afx.h
+++ b/code/nel/tools/3d/plugin_max/nel_export/std_afx.h
@@ -73,4 +73,6 @@ namespace std
 #include "nel/misc/bsphere.h"
 #include "nel/misc/path.h"
 
+#include "../nel_3dsmax_shared/string_common.h"
+
 #endif
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.cpp
index 37a79dbb5..e9230c36b 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/StdAfx.cpp
@@ -17,3 +17,5 @@
 
 #include "stdafx.h"
 
+void nlmax_mesh_library_stdafx_dummy() { }
+
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
index 5d23c25fa..031596932 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
@@ -128,7 +128,7 @@ void SLightBuild::convertFromMaxLight (INode *node,TimeValue tvTime)
 	if (maxLight->EvalLightState(tvTime, valid, &ls)!=REF_SUCCEED)
 		return;
 
-	this->Name = tStrToUtf8(node->GetName());
+	this->Name = MCharStrToUtf8(node->GetName());
 
 	// Retrieve the correct light Group Name
 	this->AnimatedLight = CExportNel::getAnimatedLight (node);
@@ -295,7 +295,7 @@ void SLightBuild::convertFromMaxLight (INode *node,TimeValue tvTime)
 		INode *exclNode = exclusionList[i];
 		if (exclNode) // Crashfix // FIXME: Why is this NULL?
 		{
-			string tmp = tStrToUtf8(exclNode->GetName());
+			string tmp = MCharStrToUtf8(exclNode->GetName());
 			this->setExclusion.insert(tmp);
 		}
 	}
@@ -1930,7 +1930,7 @@ void supprLightNoInteractOne( vector<SLightBuild> &vLights, CMesh::CMeshBuild* p
 	{
 		bool bInteract = false;
 
-		if( vLights[i].setExclusion.find(tStrToUtf8(node.GetName()) ) != vLights[i].setExclusion.end() )
+		if( vLights[i].setExclusion.find(MCharStrToUtf8(node.GetName()) ) != vLights[i].setExclusion.end() )
 		{
 			bInteract = false;
 		}
@@ -2005,7 +2005,7 @@ void CExportNel::deleteLM(INode& ZeNode)
 		string sSaveName;
 		sSaveName = _Options.sExportLighting;
 		if( sSaveName[sSaveName.size()-1] != '\\' ) sSaveName += "\\";
-		sSaveName += tStrToUtf8(ZeNode.GetName());
+		sSaveName += MCharStrToUtf8(ZeNode.GetName());
 		char tmp[32];
 		sprintf( tmp, "%d", i );
 		sSaveName += tmp;
@@ -2276,7 +2276,7 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB
 		{
 			string thetext;
 			thetext = "Warning ";
-			thetext += tStrToUtf8(ZeNode.GetName());
+			thetext += MCharStrToUtf8(ZeNode.GetName());
 			thetext = "have all faces NOT mapped (UV2)";
 			if (gOptions.FeedBack != NULL)
 			{
@@ -2325,11 +2325,11 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB
 				{
 					// Make an error message
 					string sTmp = "Warning : ";
-					sTmp += tStrToUtf8(ZeNode.GetName());
+					sTmp += MCharStrToUtf8(ZeNode.GetName());
 					sTmp += " has mapping problem";
 
 					// Script trace
-					mprintf (utf8ToTStr((sTmp+"\n")));
+					mprintf(_M("%s\n"), MaxTStrFromUtf8(sTmp).data());
 
 					// Feedback is here ?
 					if (gOptions.FeedBack != NULL)
@@ -2530,7 +2530,7 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB
 		// Add lightmap information in the lightmap log
 		COFile outputLog;
 		if (outputLightmapLog)
-			createLightmapLog(outputLog, gOptions.sExportLighting.c_str(), ucstring(projectName).toUtf8(), CStr(ZeNode.GetName()).data());
+			createLightmapLog(outputLog, gOptions.sExportLighting.c_str(), ucstring(projectName).toUtf8().c_str(), CStr(ZeNode.GetName()).data());
 
 		// Update UV coords to Texture space
 		PutFaceUV1InTextureCoord( LightMap.w, LightMap.h, AllFaces.begin(), AllFaces.size() );
@@ -2559,7 +2559,7 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB
 			{
 				CTextureFile *pLightMap = new CTextureFile();
 				//string sSaveName = AllMeshBuilds[nNode].second->GetName();
-				string sSaveName = tStrToUtf8(ZeNode.GetName());
+				string sSaveName = MCharStrToUtf8(ZeNode.GetName());
 				char tmp[32];
 				sSaveName += "_";
 				sprintf( tmp, "%d", nLightMapNb );
@@ -2633,7 +2633,7 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB
 					if (gOptions.FeedBack != NULL)
 					{
 						std::string message = toString("Can't write the file %s : %s", sSaveName.c_str(), e.what());
-						mprintf (utf8ToTStr(message));
+						mprintf(_M("%s\n"), MaxTStrFromUtf8(message).data());
 					}
 				}
 
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm_rt.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm_rt.cpp
index 1a89c8d31..c35ff796e 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm_rt.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm_rt.cpp
@@ -113,7 +113,7 @@ void CRTWorld::build (vector<SLightBuild> &AllLights, CVector &trans, bool bExcl
 				pLAP->create( 64 ); // width of each grid in number of square
 				for( j = 0; j < vMB.size(); ++j )
 				{
-					if (rLight.setExclusion.find (tStrToUtf8(vINode[j]->GetName())) != rLight.setExclusion.end())
+					if (rLight.setExclusion.find (MCharStrToUtf8(vINode[j]->GetName())) != rLight.setExclusion.end())
 						continue;
 					
 					for (k = 0; k < vMB[j]->Faces.size(); ++k)
@@ -142,7 +142,7 @@ void CRTWorld::build (vector<SLightBuild> &AllLights, CVector &trans, bool bExcl
 				pLAD->create (64, rLight.rDirRadius/64.0f, rLight.Direction);
 				for( j = 0; j < vMB.size(); ++j )
 				{
-					if (rLight.setExclusion.find (tStrToUtf8(vINode[j]->GetName())) != rLight.setExclusion.end())
+					if (rLight.setExclusion.find (MCharStrToUtf8(vINode[j]->GetName())) != rLight.setExclusion.end())
 						continue;
 					
 					for (k = 0; k < vMB[j]->Faces.size(); ++k)
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_anim.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_anim.cpp
index d55312af6..d3ef46de3 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_anim.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_anim.cpp
@@ -189,7 +189,7 @@ void CExportNel::addSSSTrack(CSSSBuild	&ssBuilder, INode& node)
             if(note)
             {
 				CSSSBuild::CKey		ks;
-				ks.Value = note->note.ToUTF8();
+				ks.Value = MaxTStrToUtf8(note->note);
 				ks.Time= CExportNel::convertTime (note->time);
 				bs.Track.push_back(ks);
             }
@@ -228,7 +228,7 @@ NL3D::CTrackKeyFramerConstString*		CExportNel::buildFromNoteTrack(INode& node)
 				{
 					firstDate = CExportNel::convertTime (note->time);
 				}				
-				ks.Value = note->note.ToUTF8();
+				ks.Value = MaxTStrToUtf8(note->note);
 				lastDate = CExportNel::convertTime (note->time);
 				st->addKey(ks , lastDate );
 				
@@ -609,7 +609,7 @@ void CExportNel::addMorphTracks (NL3D::CAnimation& animation, INode& node, const
 		if (pNode == NULL)
 			continue;
 		std::string name = parentName;
-		name += tStrToUtf8(pNode->GetName());
+		name += MCharStrToUtf8(pNode->GetName());
 		name += "MorphFactor";
 		
 		IParamBlock *pb = (IParamBlock*)(pMorphMod->SubAnim (i+1));
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_collision.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_collision.cpp
index d9657cd68..58f0db1d7 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_collision.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_collision.cpp
@@ -73,7 +73,7 @@ CCollisionMeshBuild*	CExportNel::createCollisionMeshBuild(std::vector<INode *> &
 				{
 					// get the mesh name
 					uint	meshId = rootMeshNames.size();
-					rootMeshNames.push_back(tStrToUtf8(nodes[node]->GetName()));
+					rootMeshNames.push_back(MCharStrToUtf8(nodes[node]->GetName()));
 					bool	collision = getScriptAppData (nodes[node], NEL3D_APPDATA_COLLISION, 0) != 0;
 					bool	exterior = getScriptAppData (nodes[node], NEL3D_APPDATA_COLLISION_EXTERIOR, 0) != 0;
 
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_material.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_material.cpp
index f7c8135ad..89e8a8aa2 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_material.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_material.cpp
@@ -768,7 +768,7 @@ void CExportNel::buildAMaterial (NL3D::CMaterial& material, CMaxMaterialInfo& ma
 
 		// Set material name		
 		TSTR name=mtl.GetName();
-		materialInfo.MaterialName = name.ToUTF8();
+		materialInfo.MaterialName = MaxTStrToUtf8(name);
 	}
 	else
 	{
@@ -1120,7 +1120,7 @@ void CExportNel::buildAMaterial (NL3D::CMaterial& material, CMaxMaterialInfo& ma
 
 		// Set material name		
 		TSTR name=mtl.GetName();
-		materialInfo.MaterialName = name.ToUTF8();
+		materialInfo.MaterialName = MaxTStrToUtf8(name);
 	}
 }
 
@@ -1255,7 +1255,7 @@ ITexture* CExportNel::buildATexture (Texmap& texmap, CMaterialDesc &remap3dsTexC
 		else // standard texture
 		{
 			srcTex = new CTextureFile;
-			std::string mapName = tStrToUtf8(pBitmap->GetMapName());
+			std::string mapName = MCharStrToUtf8(pBitmap->GetMapName());
 			static_cast<CTextureFile *>(srcTex)->setFileName (ConvertTexFileName(mapName, _AbsolutePath));
 		}
 
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh.cpp
index d39020a64..208e2c4fc 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh.cpp
@@ -266,7 +266,7 @@ NL3D::IShape *CExportNel::buildShape (INode& node, TimeValue time, const TInodeP
 							std::string nodeName=getScriptAppData (&node, NEL3D_APPDATA_LOD_NAME+lod, "");
 
 							// Get the node
-							INode *lodNode=_Ip->GetINodeByName(utf8ToTStr(nodeName));
+							INode *lodNode=_Ip->GetINodeByName(MaxTStrFromUtf8(nodeName).data());
 							if (lodNode)
 							{
 								// Index of the lod in the build structure
@@ -611,7 +611,7 @@ void CExportNel::buildBaseMeshInterface (NL3D::CMeshBase::CMeshBaseBuild& buildM
 			continue;
 		// get factor here !
 		buildMesh.DefaultBSFactors.push_back(0.0f);
-		std::string sTemp = tStrToUtf8(pNode->GetName());
+		std::string sTemp = MCharStrToUtf8(pNode->GetName());
 		buildMesh.BSNames.push_back (sTemp);
 	}
 
@@ -1045,7 +1045,7 @@ void CExportNel::buildMeshInterface (TriObject &tri, CMesh::CMeshBuild& buildMes
 			if (!vpColorVertex)
 			{
 				uint8 alphaBackup = pCorner->Color.A;
-				pCorner->Color.modulateFromColor (pCorner->Color, isLighted ? diffuse : color);
+				pCorner->Color.modulateFromColor(pCorner->Color, isLighted ? diffuse : color);
 				pCorner->Color.A = alphaBackup;
 			}
 		}
@@ -1058,18 +1058,18 @@ void CExportNel::buildMeshInterface (TriObject &tri, CMesh::CMeshBuild& buildMes
 	if (skined)
 	{
 		// Add skinning information to the buildMesh struct
-		uint error=buildSkinning (buildMesh, *nodeMap, node);
+		uint error = buildSkinning (buildMesh, *nodeMap, node);
 
 		// Error code ?
 		if (error!=NoError)
 		{
-			std::string msg = toString("%s skin: %s", getName (node).c_str(), ErrorMessage[error]);
-			MessageBoxW (NULL, utf8ToTStr(msg), L"NeL export", MB_OK|MB_ICONEXCLAMATION);
+			std::string msg = toString("%s skin: %s", getName(node).c_str(), ErrorMessage[error]);
+			MessageBox(NULL, MaxTStrFromUtf8(msg).data(), _T("NeL export"), MB_OK | MB_ICONEXCLAMATION);
 		}
 		else
 		{
 			// Active skinning
-			buildMesh.VertexFlags|=CVertexBuffer::PaletteSkinFlag;
+			buildMesh.VertexFlags |= CVertexBuffer::PaletteSkinFlag;
 		}
 	}
 
@@ -1082,7 +1082,7 @@ void CExportNel::buildMeshInterface (TriObject &tri, CMesh::CMeshBuild& buildMes
 	buildMesh.InterfaceLinks.clear();
 
 	// don't do it for morph target (unusefull and slow)
-	if(!isMorphTarget)
+	if (!isMorphTarget)
 	{
 		// Apply normal correction if there is a mesh interface
 		if (skined)
@@ -1118,41 +1118,41 @@ void CExportNel::buildMeshInterface (TriObject &tri, CMesh::CMeshBuild& buildMes
 	else  // standard case
 	{
 		// What Vertexprogram is used??
-		int	vpId= CExportNel::getScriptAppData (&node, NEL3D_APPDATA_VERTEXPROGRAM_ID, 0);
+		int	vpId = CExportNel::getScriptAppData (&node, NEL3D_APPDATA_VERTEXPROGRAM_ID, 0);
 		// Setup vertexProgram
 		switch(vpId)
 		{
 			case 0: 
-				buildMesh.MeshVertexProgram= NULL;
+				buildMesh.MeshVertexProgram = NULL;
 				break;
 			case 1:
 			{
 				// smartPtr set it.
-				buildMesh.MeshVertexProgram= new CMeshVPWindTree;
-				CMeshVPWindTree		&vpwt= *(CMeshVPWindTree*)(IMeshVertexProgram*)buildMesh.MeshVertexProgram;
+				buildMesh.MeshVertexProgram = new CMeshVPWindTree;
+				CMeshVPWindTree &vpwt = *(CMeshVPWindTree*)(IMeshVertexProgram*)buildMesh.MeshVertexProgram;
 
 				// Read the AppData
-				CVPWindTreeAppData	apd;
-				getScriptAppDataVPWT (&node, apd);
+				CVPWindTreeAppData apd;
+				getScriptAppDataVPWT(&node, apd);
 
 				// transform it to the vpwt.
 				nlassert(CVPWindTreeAppData::HrcDepth == CMeshVPWindTree::HrcDepth);
 				vpwt.SpecularLighting= apd.SpecularLighting == BST_CHECKED;
 				// read all levels.
-				float	nticks= CVPWindTreeAppData::NumTicks;
-				for(uint i=0; i<CVPWindTreeAppData::HrcDepth;i++)
+				float nticks = CVPWindTreeAppData::NumTicks;
+				for (uint i = 0; i < CVPWindTreeAppData::HrcDepth; i++)
 				{
-					float	scale;
+					float scale;
 					// read frequency
-					scale= apd.FreqScale;
-					vpwt.Frequency[i]= float(apd.Frequency[i])/nticks * scale;
-					vpwt.FrequencyWindFactor[i]= float(apd.FrequencyWindFactor[i])/nticks * scale;
+					scale = apd.FreqScale;
+					vpwt.Frequency[i] = float(apd.Frequency[i])/nticks * scale;
+					vpwt.FrequencyWindFactor[i] = float(apd.FrequencyWindFactor[i])/nticks * scale;
 					// read Distance
 					scale= apd.DistScale;
-					vpwt.PowerXY[i]= float(apd.DistXY[i])/nticks * scale;
-					vpwt.PowerZ[i]= float(apd.DistZ[i])/nticks * scale;
+					vpwt.PowerXY[i] = float(apd.DistXY[i])/nticks * scale;
+					vpwt.PowerZ[i] = float(apd.DistZ[i])/nticks * scale;
 					// read Bias. expand to -2,2
-					vpwt.Bias[i]= float(apd.Bias[i])/nticks*4 -2;
+					vpwt.Bias[i] = float(apd.Bias[i])/nticks*4 -2;
 				}
 
 				break;
@@ -1492,7 +1492,7 @@ void CExportNel::buildMeshMorph (CMesh::CMeshBuild& buildMesh, INode &node, Time
 			continue;
 		}
 
-		bs.Name = tStrToUtf8(pNode->GetName());
+		bs.Name = MCharStrToUtf8(pNode->GetName());
 
 		bool bIsDeltaPos = false;
 		bs.deltaPos.resize (nNbVertVB, CVector::Null);
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh_interface.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh_interface.cpp
index 0cbd8fbe1..6dd2e1ee4 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh_interface.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_mesh_interface.cpp
@@ -316,7 +316,7 @@ static void AddNodeToQuadGrid(const NLMISC::CAABBox &delimiter, TNodeFaceQG &des
 	{
 		if (delimiter.intersect(nodeBBox))
 		{
-			nldebug("Adding %s to mesh interface quad grid", tStrToUtf8(node.GetName()).c_str());
+			nldebug("Adding %s to mesh interface quad grid", MCharStrToUtf8(node.GetName()).c_str());
 			// add this node tris
 			ObjectState os = node.EvalWorldState(time);
 			Object *obj = os.obj;	
@@ -578,10 +578,10 @@ static bool BuildMeshInterfaces(const char *cMaxFileName, std::vector<CMeshInter
 	for (i=0; i<size; i++)
 	{
 		// Rename the material
-		string newName = "NelAutoMergeRenamedTmp" + toString (i);
-		string originalName = (*lib)[i]->GetName ().ToUTF8();
+		string newName = "NelAutoMergeRenamedTmp" + toString(i);
+		string originalName = MaxTStrToUtf8((*lib)[i]->GetName());
 		renameMap.insert (map<string, string>::value_type (newName, originalName));
-		(*lib)[i]->SetName (utf8ToTStr(newName));
+		(*lib)[i]->SetName (MaxTStrFromUtf8(newName));
 	}
 
 	// Merge the interface project
@@ -604,7 +604,7 @@ static bool BuildMeshInterfaces(const char *cMaxFileName, std::vector<CMeshInter
 	for (i=0; i<size; i++)
 	{
 		// Find the name in the map ?
-		string key = (*lib)[i]->GetName ().ToUTF8();
+		string key = MaxTStrToUtf8((*lib)[i]->GetName());
 		map<string, string>::iterator ite = renameMap.find (key);
 
 		// Not found ? This is a merged material
@@ -612,9 +612,9 @@ static bool BuildMeshInterfaces(const char *cMaxFileName, std::vector<CMeshInter
 		{
 			// Rename the material
 			string newName = "NelAutoMergeRenamed" + toString (i);
-			string originalName = (*lib)[i]->GetName ().ToUTF8();
+			string originalName = MaxTStrToUtf8((*lib)[i]->GetName());
 			renameMap.insert (map<string, string>::value_type (newName, originalName));
-			(*lib)[i]->SetName (utf8ToTStr(newName));
+			(*lib)[i]->SetName (MaxTStrFromUtf8(newName));
 		}
 	}
 
@@ -622,12 +622,12 @@ static bool BuildMeshInterfaces(const char *cMaxFileName, std::vector<CMeshInter
 	for (i=0; i<size; i++)
 	{
 		// Find the name
-		string key = (*lib)[i]->GetName ().ToUTF8();
+		string key = MaxTStrToUtf8((*lib)[i]->GetName());
 		map<string, string>::iterator ite = renameMap.find (key);
 		if (ite != renameMap.end ())
 		{
 			// Rename the material with its original name
-			(*lib)[i]->SetName (utf8ToTStr(ite->second));
+			(*lib)[i]->SetName (MaxTStrFromUtf8(ite->second));
 		}
 	}
 
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp
index 7af1a7bc5..b47b05e84 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp
@@ -223,7 +223,7 @@ Animatable*	CExportNel::getSubAnimByName (Animatable& node, const char* sName)
 		TSTR sSubName=node.SubAnimName(nSub);
 
 		// Good name?
-		if (strcmp (sSubName.ToUTF8(), sName)==0)
+		if (strcmp (MaxTStrToUtf8(sSubName).c_str(), sName)==0)
 		{
 			// ok, return this subanim
 			return node.SubAnim(nSub);
@@ -265,7 +265,7 @@ Control* CExportNel::getControlerByName (Animatable& node, const char* sName)
 			ParamDef& paramDef=param->GetParamDef(id);
 
 			// Good name?
-			if (strcmp (tStrToUtf8(paramDef.int_name).c_str(), sName)==0)
+			if (strcmp (MCharStrToUtf8(paramDef.int_name).c_str(), sName)==0)
 			{
 				// ok, return this subanim
 #if MAX_VERSION_MAJOR >= 14
@@ -288,7 +288,7 @@ Control* CExportNel::getControlerByName (Animatable& node, const char* sName)
 		{
 			// Sub anim name
 			TSTR name=node.SubAnimName (s);
-			if (strcmp (name.ToUTF8(), sName)==0)
+			if (strcmp (MaxTStrToUtf8(name).c_str(), sName)==0)
 			{
 				// Get the controller pointer of this sub anim
 				Control* c=GetControlInterface (node.SubAnim(s));
@@ -332,7 +332,7 @@ bool getValueByNameUsingParamBlock2Internal (Animatable& node, const char* sName
 			ParamDef& paramDef=param->GetParamDef(id);
 
 			// Good name?
-			if (strcmp (tStrToUtf8(paramDef.int_name).c_str(), sName)==0)
+			if (strcmp (MCharStrToUtf8(paramDef.int_name).c_str(), sName)==0)
 			{
 				// Check this value is good type
 				ParamType2 paramType = param->GetParameterType(id);
@@ -372,7 +372,7 @@ bool getValueByNameUsingParamBlock2Internal (Animatable& node, const char* sName
 						break;
 						case TYPE_FILENAME:
 						case TYPE_STRING:
-							*(std::string*)pValue = tStrToUtf8(param->GetStr (id, tvTime));
+							*(std::string*)pValue = MCharStrToUtf8(param->GetStr (id, tvTime));
 							bRes = TRUE;
 						break;
 						case TYPE_FILENAME_TAB:
@@ -382,7 +382,7 @@ bool getValueByNameUsingParamBlock2Internal (Animatable& node, const char* sName
 							uint total = param->Count (id);
 							rTab.resize(total);
 							for( uint i = 0; i < total; ++i )
-								rTab[i] = tStrToUtf8(param->GetStr (id, tvTime, i));
+								rTab[i] = MCharStrToUtf8(param->GetStr (id, tvTime, i));
 							bRes = TRUE;
 						}
 						break;
@@ -502,7 +502,7 @@ std::string	CExportNel::getName (MtlBase& mtl)
 	// Return its name
 	TSTR name;
 	name=mtl.GetName();
-	return std::string((const char*)name.ToUTF8());
+	return MaxTStrToUtf8(name);
 }
 
 // --------------------------------------------------
@@ -511,8 +511,8 @@ std::string	CExportNel::getName (MtlBase& mtl)
 std::string	CExportNel::getName(INode& node)
 {
 	// Return its name
-	const MCHAR* name = node.GetName();
-	return tStrToUtf8(name);
+	const MCHAR *name = node.GetName();
+	return MCharStrToUtf8(name);
 }
 
 // --------------------------------------------------
@@ -549,7 +549,7 @@ std::string		CExportNel::getNelObjectName (INode& node)
 		}
 		else
 		{
-			return tStrToUtf8(node.GetName());
+			return MCharStrToUtf8(node.GetName());
 		}
 	}
 	else
@@ -564,23 +564,23 @@ std::string		CExportNel::getNelObjectName (INode& node)
 				if (_tcslen((const TCHAR *) ad->data) != 0)
 				{
 					// get file name only
-					return NLMISC::CFile::getFilename(tStrToUtf8((const TCHAR*)ad->data));
+					return NLMISC::CFile::getFilename(MCharStrToUtf8((const MCHAR*)ad->data));
 				}
 				else
 				{
-					return tStrToUtf8(node.GetName());
+					return MCharStrToUtf8(node.GetName());
 				}
 			}
 			else
 			{
 				// Extract the node name
-				return tStrToUtf8(node.GetName());
+				return MCharStrToUtf8(node.GetName());
 			}
 		}
 		else
 		{
 			// Extract the node name
-			return tStrToUtf8(node.GetName());
+			return MCharStrToUtf8(node.GetName());
 		}
 	}
 }
@@ -764,28 +764,26 @@ void CExportNel::outputErrorMessage(const std::string &message)
 {
 	if (_ErrorInDialog)
 	{
-		MessageBoxW (_Ip->GetMAXHWnd(), utf8ToTStr(message), utf8ToTStr(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
+		MessageBoxW(_Ip->GetMAXHWnd(), utf8ToWide(message), utf8ToWide(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
 	}
-	mprintf (utf8ToTStr(message));
-	mprintf (_T("\n"));
+	mprintf(_M("%s\n"), MaxTStrFromUtf8(message).data());
 
-	nlwarning ("Error in max file %s : ", _Ip->GetCurFilePath());
-	nlwarning (message.c_str());
+	nlwarning("Error in max file %s : ", _Ip->GetCurFilePath());
+	nlwarning("%s", message.c_str());
 }
 
 // --------------------------------------------------
 
-void CExportNel::outputWarningMessage (const std::string &message)
+void CExportNel::outputWarningMessage(const std::string &message)
 {
 	if (_ErrorInDialog)
 	{
-		MessageBox (_Ip->GetMAXHWnd(), utf8ToTStr(message), utf8ToTStr(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
+		MessageBoxW(_Ip->GetMAXHWnd(), utf8ToWide(message), utf8ToWide(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
 	}
-	mprintf (utf8ToTStr(message));
-	mprintf (_M("\n"));
+	mprintf(_M("%s\n"), MaxTStrFromUtf8(message).data());
 
-	nlwarning ("Warning in max file %s : ", _Ip->GetCurFilePath());
-	nlwarning (message.c_str());
+	nlwarning("Warning in max file %s : ", _Ip->GetCurFilePath());
+	nlwarning("%s", message.c_str());
 }
 
 // --------------------------------------------------
@@ -819,7 +817,7 @@ void CExportNel::addChildLodNode (std::set<INode*> &lodListToExclude, INode *cur
 		if (lodName != "")
 		{
 			// Get the lod by name
-			INode *lodNode = _Ip->GetINodeByName (utf8ToTStr(lodName));
+			INode *lodNode = _Ip->GetINodeByName(MaxTStrFromUtf8(lodName));
 			if (lodNode)
 			{
 				// Insert it in the set
@@ -850,7 +848,7 @@ void CExportNel::addParentLodNode (INode &child, std::set<INode*> &lodListToExcl
 		if (lodName != "")
 		{
 			// Get the lod by name
-			INode *lodNode = _Ip->GetINodeByName (utf8ToTStr(lodName));
+			INode *lodNode = _Ip->GetINodeByName(MaxTStrFromUtf8(lodName));
 			if (lodNode == &child)
 			{
 				// Insert it in the set
@@ -1111,7 +1109,7 @@ static void restoreDecimalSeparator()
 float toFloatMax(const TCHAR *src)
 {
 	float result = 0.f;
-	if (toFloatMax(tStrToUtf8(src), result)) return result;
+	if (toFloatMax(MCharStrToUtf8(src), result)) return result;
 	return 0.f;
 }
 
@@ -1124,7 +1122,7 @@ float toFloatMax(const std::string &src)
 
 bool toFloatMax(const TCHAR *src, float &dest)
 {
-	return toFloatMax(tStrToUtf8(src), dest);
+	return toFloatMax(MCharStrToUtf8(src), dest);
 }
 
 bool toFloatMax(const std::string &src, float &dest)
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp
index 4b17b17d3..02e3f9018 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_particle_system.cpp
@@ -51,7 +51,7 @@ IShape* CExportNel::buildParticleSystem(INode& node, TimeValue time)
 			iF.serial(ss);
 			if (!dynamic_cast<CParticleSystemShape *>(ss.getShapePointer()))
 			{
-				mprintf(_T("Error : Object shape %s isn't a particle system"), utf8ToTStr(shapeName));
+				mprintf(_M("Error : Object shape %s isn't a particle system\n"), MaxTStrFromUtf8(shapeName).data());
 				return NULL;
 			}
 
@@ -78,7 +78,7 @@ IShape* CExportNel::buildParticleSystem(INode& node, TimeValue time)
 		}
 		else
 		{
-			mprintf(_T("Error : Can't find %s while exporting a particle system \n"), utf8ToTStr(shapeName));
+			mprintf(_M("Error : Can't find %s while exporting a particle system\n"), MaxTStrFromUtf8(shapeName).data());
 			return NULL;
 		}				
 	}
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_radial_normal.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_radial_normal.cpp
index 80f57bfb4..91fcd99db 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_radial_normal.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_radial_normal.cpp
@@ -62,7 +62,7 @@ void CRadialVertices::init (INode *node, Mesh *mesh, TimeValue time, Interface &
 			_SmoothingGroupMask |= (1<<app);
 
 			// Get the node by name
-			INode *pivotNode = ip.GetINodeByName(utf8ToTStr(pivotName));
+			INode *pivotNode = ip.GetINodeByName(MaxTStrFromUtf8(pivotName));
 			if (pivotNode)
 			{
 				// Get the world Pivot point
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp
index cd8fcb5b7..63bf28a49 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_scene.cpp
@@ -93,7 +93,7 @@ CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, v
 			resultInstanceNode[nNumIG] = pNode;
 			if (aIGArray[nNumIG].InstanceName == "") // no instance name was set, takes the node name instead
 			{
-				aIGArray[nNumIG].InstanceName = tStrToUtf8(pNode->GetName());
+				aIGArray[nNumIG].InstanceName = MCharStrToUtf8(pNode->GetName());
 			}
 
 			// Visible? always true, but if special flag for camera collision
@@ -236,7 +236,7 @@ CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, v
 											 pMB->Vertices[pMB->Faces[j].Corner[2].Vertex]) )
 				{
 					// ERROR : The volume is not convex !!!
-					nlwarning("ERROR: The cluster %s is not convex.", tStrToUtf8(vectNode[i]->GetName()).c_str());
+					nlwarning("ERROR: The cluster %s is not convex.", MCharStrToUtf8(vectNode[i]->GetName()).c_str());
 				}
 			}
 
@@ -244,7 +244,7 @@ CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, v
 			clusterTemp.VisibleFromFather = bVisibleFromFather;
 			clusterTemp.FatherAudible = bFatherAudible;
 			clusterTemp.AudibleFromFather = bAudibleFromFather;
-			clusterTemp.Name = tStrToUtf8(pNode->GetName());
+			clusterTemp.Name = MCharStrToUtf8(pNode->GetName());
 
 			vClusters.push_back (clusterTemp);
 			delete pMB; pMB = NULL;
@@ -333,7 +333,7 @@ CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, v
 			if (!portalTemp.setPoly (polyv))
 			{
 				// ERROR : Poly not convex, or set of vertices not plane
-				nlwarning("ERROR: The portal %s is not convex.", tStrToUtf8(vectNode[i]->GetName()).c_str());
+				nlwarning("ERROR: The portal %s is not convex.", MCharStrToUtf8(vectNode[i]->GetName()).c_str());
 			}
 
 			if (nAccelType&16) // is dynamic portal ?
@@ -342,7 +342,7 @@ CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, v
 				if (!InstanceName.empty())
 					portalTemp.setName (InstanceName);
 				else
-					portalTemp.setName (tStrToUtf8(pNode->GetName()));
+					portalTemp.setName (MCharStrToUtf8(pNode->GetName()));
 			}
 
 			// Check if portal has 2 cluster
@@ -362,7 +362,7 @@ CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, v
 			if (nNbCluster != 2)
 			{
 				// ERROR
-				nlwarning("ERROR: The portal %s has not 2 clusters but %d", tStrToUtf8(vectNode[i]->GetName()).c_str(), nNbCluster);
+				nlwarning("ERROR: The portal %s has not 2 clusters but %d", MCharStrToUtf8(vectNode[i]->GetName()).c_str(), nNbCluster);
 			}
 
 
@@ -504,7 +504,7 @@ CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, v
 				if (!vClusters.empty())
 				if (aIGArray[nNumIG].Clusters.empty())
 				{
-					nlwarning("ERROR: Object %s is not attached to any cluster\nbut his flag clusterize is set", tStrToUtf8(pNode->GetName()).c_str());
+					nlwarning("ERROR: Object %s is not attached to any cluster\nbut his flag clusterize is set", MCharStrToUtf8(pNode->GetName()).c_str());
 				}
 				// debug purpose : to remove
 
@@ -700,7 +700,7 @@ void CExportNel::buildScene (NL3D::CScene &scene, NL3D::CShapeBank &shapeBank, I
 		if ( (!pNode->IsHidden () || buildHidden) && (pNode->Selected () || !onlySelected) )
 		{
 			string sTmp = "Object Name: ";
-			sTmp += tStrToUtf8(pNode->GetName());
+			sTmp += MCharStrToUtf8(pNode->GetName());
 			if (progress)
 				progress->setLine (0, sTmp);
 			sTmp.clear();
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp
index cf99e2c0c..1d495abc7 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_script.cpp
@@ -36,7 +36,7 @@ bool CExportNel::scriptEvaluate (const char *script, void *out, TNelScriptValueT
 	four_typed_value_locals(Parser* parser,Value* code,Value* result,StringStream* source);
 
 	vl.parser = new Parser;
-	vl.source = new StringStream (utf8ToTStr(script));
+	vl.source = new StringStream(MaxTStrFromUtf8(script));
 	vl.source->log_to(NULL);
 
 #if MAX_VERSION_MAJOR < 19
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_skinning.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_skinning.cpp
index d5030ee9d..e099dc1c3 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_skinning.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_skinning.cpp
@@ -114,7 +114,7 @@ INode *CExportNel::getNELScaleReferenceNode(INode &node)
 		{
 			std::string	boneScaleName= getName(node) + boneScaleNameExt;
 			// Get the reference node
-			referenceNode= _Ip->GetINodeByName(utf8ToTStr(boneScaleName));
+			referenceNode= _Ip->GetINodeByName(MaxTStrFromUtf8(boneScaleName));
 		}
 	}
 
@@ -455,7 +455,7 @@ uint CExportNel::buildSkinning (CMesh::CMeshBuild& buildMesh, const TInodePtrInt
 		nlassert ((uint)ite->second<buildMesh.BonesNames.size());
 
 		// Names
-		buildMesh.BonesNames[ite->second] = tStrToUtf8(ite->first->GetName());
+		buildMesh.BonesNames[ite->second] = MCharStrToUtf8(ite->first->GetName());
 
 		// Next
 		ite++;
@@ -1306,7 +1306,7 @@ static sint	getBoneSide(INode *bone, std::string &mirrorName)
 {
 	sint	side= 0;
 	sint	pos;
-	mirrorName = tStrToUtf8(bone->GetName());
+	mirrorName = MCharStrToUtf8(bone->GetName());
 
 	if((pos= mirrorName.find(" R "))!=std::string::npos)
 	{
@@ -1335,7 +1335,7 @@ static INode *getMirrorBone(const std::vector<INode*>	&skeletonNodes, INode *bon
 		// find
 		for(uint i=0;i<skeletonNodes.size();i++)
 		{
-			if(mirrorName == tStrToUtf8(skeletonNodes[i]->GetName()))
+			if(mirrorName == MCharStrToUtf8(skeletonNodes[i]->GetName()))
 				return skeletonNodes[i];
 		}
 	}
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/PO2RPO.h b/code/nel/tools/3d/plugin_max/nel_patch_converter/PO2RPO.h
index 77c2c03ca..34e3da363 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_converter/PO2RPO.h
+++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/PO2RPO.h
@@ -33,14 +33,14 @@
 #undef max
 #endif
 
+#include "../nel_3dsmax_shared/string_common.h"
+
 #define PO2RPO_CLASS_ID Class_ID(0x43bb65e6, 0x68935530)
 
 extern TCHAR *GetString(int id);
 
 extern HINSTANCE hInstance;
 
-
-
 class PO2RPO : public Modifier {
 	public:
 		// Parameter block
@@ -50,7 +50,7 @@ class PO2RPO : public Modifier {
 		HWND hRollup;
 
 		// From Animatable
-		const MCHAR *GetObjectName() { return GetString(IDS_CLASS_NAME); }
+		GET_OBJECT_NAME_CONST MCHAR *GetObjectName() { return GetString(IDS_CLASS_NAME); }
 
 		//From Modifier
 		//TODO: Add the channels that the modifier needs to perform its modification
@@ -87,7 +87,7 @@ class PO2RPO : public Modifier {
 		void GetClassName(TSTR& s) {s = GetString(IDS_CLASS_NAME);}
 		
 		RefTargetHandle Clone( RemapDir &remap );
-		RefResult NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget, PartID& partID,  RefMessage message, BOOL propagate);
+		RefResult NotifyRefChanged(NOTIFY_REF_PARAMS);
 
 		int NumSubs() { return 0; }
 		TSTR SubAnimName(int i) { return GetString(IDS_PARAMS); }
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.cpp b/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.cpp
index ee75bc152..4b7483057 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/nel_patch_converter.cpp
@@ -44,8 +44,8 @@ static ParamBlockDesc2 po2rpo_param_blk ( po2rpo_params, _T("params"),  0, &PO2R
 		p_default, 		0.1f,
 		p_range, 		0.0f,1000.0f,
 		p_ui, 			TYPE_SPINNER,		EDITTYPE_FLOAT, IDC_EDIT,	IDC_SPIN, 0.01f,
-		p_end,
-	p_end
+		nl_p_end,
+	nl_p_end
 	);
 
 IObjParam *PO2RPO::ip			= NULL;
@@ -142,7 +142,7 @@ INT_PTR CALLBACK DlgProc_Panel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
 					if (versionInfoSize)
 					{
 						// Alloc the buffer (size in bytes)
-						uint8_t *buffer = new uint8_t[versionInfoSize];
+						uint8 *buffer = new uint8[versionInfoSize];
 
 						// Find the verion resource
 						if (GetFileVersionInfo(moduldeFileName, 0, versionInfoSize, buffer))
@@ -174,7 +174,7 @@ INT_PTR CALLBACK DlgProc_Panel(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
 							SetWindowText (GetDlgItem (hWnd, IDC_VERSION), _T("GetFileVersionInfo failed"));
 
 						// Free the buffer
-						delete [] buffer;
+						delete[] buffer;
 					}
 					else
 						SetWindowText (GetDlgItem (hWnd, IDC_VERSION), _T("GetFileVersionInfoSize failed"));
@@ -221,7 +221,7 @@ void PO2RPO::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next)
 // -----------------------------------------------------------------------------------------------------------------------------------------------------------
 
 //From ReferenceMaker
-RefResult PO2RPO::NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate)
+RefResult PO2RPO::NotifyRefChanged(NOTIFY_REF_PARAMS)
 {
 	//TODO: Add code to handle the various reference changed messages
 	return REF_SUCCEED;
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp b/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp
index 7ce6c3068..8ceaddb6e 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_converter/script.cpp
@@ -216,7 +216,7 @@ export_zone_cf (Value** arg_list, int count)
 			if (tri->rpatch->exportZone (node, &tri->patch, zone, zoneSymmetry, nZone, 160, 1, false))
 			{
 				// Export path 
-				const std::string sPath = tStrToUtf8(arg_list[1]->to_string());
+				const std::string sPath = MCharStrToUtf8(arg_list[1]->to_string());
 
 				COFile file;
 				if (file.open (sPath))
@@ -246,7 +246,7 @@ Value* import_zone_cf (Value** arg_list, int count)
 	Interface *ip = MAXScript_interface;
 
 	// Get the filename
-	string filename = tStrToUtf8(arg_list[0]->to_string());
+	string filename = MCharStrToUtf8(arg_list[0]->to_string());
 
 	// Get the flip
 	bool dialog = arg_list[1]->to_bool ()!=FALSE;
@@ -289,14 +289,14 @@ Value* import_zone_cf (Value** arg_list, int count)
 		{
 			// Error message
 			std::string msg = toString("Error when loading file %s: %s", filename.c_str(), e.what());
-			errorMessage (utf8ToTStr(msg), _T("NeL import zone"), *ip, dialog);
+			errorMessage (MaxTStrFromUtf8(msg), _M("NeL import zone"), *ip, dialog);
 		}
 	}
 	else
 	{
 		// Error message
 		std::string msg = toString("Can't open the file %s for reading.", filename.c_str());
-		errorMessage (utf8ToTStr(msg), _T("NeL import zone"), *ip, dialog);
+		errorMessage (MaxTStrFromUtf8(msg), _M("NeL import zone"), *ip, dialog);
 	}
 
 	return ret;
@@ -1708,7 +1708,7 @@ Value* set_tile_bank_cf (Value** arg_list, int count)
 	type_check(arg_list[0], String, _M("NelSetTileBank [tile bank pathname]"));
 
 	// ok ?
-	const std::string pathname = tStrToUtf8(arg_list[0]->to_string());
+	const std::string pathname = MCharStrToUtf8(arg_list[0]->to_string());
 
 	// Get tile number
 	SetBankPathName (pathname);
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h b/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h
index b6fe7adb1..ea70bc788 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h
+++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/editpat.h
@@ -574,7 +574,7 @@ class EditPatchMod : public Modifier, IPatchOps, IPatchSelect, ISubMtlAPI, Attac
 		static bool		additiveTile;
 		static bool		automaticLighting;
 
-		RefResult NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate) { return REF_SUCCEED; }
+		RefResult NotifyRefChanged(NOTIFY_REF_PARAMS) { return REF_SUCCEED; }
 
 		int selLevel;
 
@@ -751,7 +751,7 @@ class EditPatchMod : public Modifier, IPatchOps, IPatchSelect, ISubMtlAPI, Attac
 		void BeginEditParams( IObjParam  *ip, ULONG flags, Animatable *prev );
 		void EndEditParams( IObjParam *ip, ULONG flags, Animatable *next );
 		RefTargetHandle Clone(RemapDir& remap = DefaultRemapDir());
-		const MCHAR *GetObjectName() { return GetString(IDS_TH_EDITPATCH); }
+		GET_OBJECT_NAME_CONST MCHAR *GetObjectName() { return GetString(IDS_TH_EDITPATCH); }
 		void ActivateSubobjSel(int level, XFormModes& modes );
 		int NeedUseSubselButton() { return 0; }
 		void SelectSubPatch(int index);
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_edit_patch_mod.cpp b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_edit_patch_mod.cpp
index 4306cfd0b..3fb6aaefb 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_edit/np_edit_patch_mod.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/np_edit_patch_mod.cpp
@@ -338,7 +338,7 @@ static INT_PTR CALLBACK PickSetDlgProc(
 			Tab<TSTR*> &names = *((Tab < TSTR*>*)lParam);
 			for (int i = 0; i < names.Count(); i++)
 			{
-				int pos  = SendDlgItemMessage(hWnd, IDC_NS_LIST, LB_ADDSTRING, 0, (LPARAM)(TCHAR*)*names[i]->ToMCHAR());
+				int pos  = SendDlgItemMessage(hWnd, IDC_NS_LIST, LB_ADDSTRING, 0, (LPARAM)(*names[i]->data()));
 				SendDlgItemMessage(hWnd, IDC_NS_LIST, LB_SETITEMDATA, pos, i);
 			}
 			break;
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_edit/stdafx.cpp b/code/nel/tools/3d/plugin_max/nel_patch_edit/stdafx.cpp
index 62eecad20..a849e7019 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_edit/stdafx.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_edit/stdafx.cpp
@@ -1 +1,3 @@
 #include "stdafx.h" 
+
+void nlmax_patch_edit_stdafx_dummy() { }
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.cpp b/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.cpp
index 90803fad1..72d31a85d 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.cpp
@@ -104,11 +104,14 @@ std::string GetBankPathName ()
 	if (RegOpenKeyEx(HKEY_CURRENT_USER, REGKEY_TILEDIT, 0, KEY_READ, &hKey)==ERROR_SUCCESS)
 	{
 		TCHAR path[256];
-		DWORD len=256 * sizeof(TCHAR);
+		DWORD len = 256 * sizeof(TCHAR);
 		DWORD type;
 		if (RegQueryValueEx(hKey, _T("Bank Path"), 0, &type, (LPBYTE)path, &len)==ERROR_SUCCESS)
-			return tStrToUtf8(path);
-		RegCloseKey (hKey);
+		{
+			RegCloseKey(hKey);
+			return MCharStrToUtf8(path);
+		}
+		RegCloseKey(hKey);
 	}
 	return "";
 }
@@ -119,11 +122,14 @@ int GetBankTileSetSet ()
 	if (RegOpenKeyEx(HKEY_CURRENT_USER, REGKEY_TILEDIT, 0, KEY_READ, &hKey)==ERROR_SUCCESS)
 	{
 		int tileSetSet;
-		DWORD len=256;
+		DWORD len = 256;
 		DWORD type;
 		if (RegQueryValueEx(hKey, _T("Tileset Set"), 0, &type, (LPBYTE)&tileSetSet, &len)==ERROR_SUCCESS)
+		{
+			RegCloseKey(hKey);
 			return tileSetSet;
-		RegCloseKey (hKey);
+		}
+		RegCloseKey(hKey);
 	}
 	return -1;
 }
@@ -134,8 +140,7 @@ void SetBankPathName (const std::string& path)
 	if (RegCreateKey(HKEY_CURRENT_USER, REGKEY_TILEDIT, &hKey)==ERROR_SUCCESS)
 	{
 		TCHAR buffer[MAX_PATH];
-		_tcscpy_s(buffer, MAX_PATH, utf8ToTStr(path));
-
+		_tcscpy_s(buffer, MAX_PATH, MaxTStrFromUtf8(path).data());
 		RegSetValueEx(hKey, _T("Bank Path"), 0, REG_SZ, (LPBYTE)buffer, (_tcslen(buffer)+1)*sizeof(TCHAR));
 		RegCloseKey (hKey);
 	}
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.h b/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.h
index f0ed9601c..e8cdf079b 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.h
+++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/nel_patch_mesh.h
@@ -30,6 +30,7 @@
 #include "nel/misc/file.h"
 #include "nel/misc/rgba.h"
 #include "path_mesh_alloc.h"
+#include "../nel_3dsmax_shared/string_common.h"
 
 //#define USE_CACHE
 
@@ -451,7 +452,7 @@ public:
 			}
 			catch (const NLMISC::EStream& excp)
 			{
-				MessageBox (NULL, utf8ToTStr(excp.what()), _T("Load error"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox (NULL, MaxTStrFromUtf8(excp.what()).data(), _T("Load error"), MB_OK|MB_ICONEXCLAMATION);
 			}
 		}
 		return _bank;
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.cpp b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.cpp
index 9216d4155..318b2902d 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.cpp
@@ -304,7 +304,7 @@ void RPO::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel )
 // ------------------------------------------------------------------------------------------------------------------------------------------------
 
 //From ReferenceMaker
-RefResult RPO::NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget,PartID& partID, RefMessage message, BOOL propagate )
+RefResult RPO::NotifyRefChanged(NOTIFY_REF_PARAMS)
 {
 	//TODO: Implement, if the object makes references to other things
 	//return PatchObject::NotifyRefChanged( changeInt, hTarget, partID, message, propagate);
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h
index 0faa95aa6..15d477d3b 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h
+++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h
@@ -83,7 +83,7 @@ class RPO : public PatchObject
 		int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt);
 		void Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt);
 		//TODO: Return the name that will appear in the history browser (modifier stack)
-		const MCHAR *GetObjectName() { return _M("Rykol Patch Object");}
+		GET_OBJECT_NAME_CONST MCHAR *GetObjectName() { return _M("Rykol Patch Object");}
 		
 		void GetWorldBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box );
 		void GetLocalBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box );
@@ -206,10 +206,10 @@ class RPO : public PatchObject
 				? true : PatchObject::IsSubClassOf(classID);
 		}
 		SClass_ID SuperClassID() { return GEOMOBJECT_CLASS_ID; }
-		void GetClassName(TSTR& s) {s.FromUTF8("Rykol Patch Object");}
+		void GetClassName(TSTR& s) { s = "Rykol Patch Object";}
 		
 		RefTargetHandle Clone ( RemapDir &remap );
-		RefResult NotifyRefChanged (const Interval& changeInt, RefTargetHandle hTarget, PartID& partID,  RefMessage message, BOOL propagate);
+		RefResult NotifyRefChanged (NOTIFY_REF_PARAMS);
 
 		int NumSubs() 
 		{ 
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp
index ea21e8fbe..6fe193a30 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo2nel.cpp
@@ -193,7 +193,7 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 				}
 				catch (const EStream& e)
 				{
-					MessageBox (NULL, utf8ToTStr(e.what()), _T("Error"), MB_OK|MB_ICONEXCLAMATION);
+					MessageBox (NULL, MaxTStrFromUtf8(e.what()).data(), _T("Error"), MB_OK|MB_ICONEXCLAMATION);
 				}
 			}
 		}
@@ -267,8 +267,8 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 		}
 
 		// Show the message
-		mprintf (utf8ToTStr(error));
-		nlwarning (error.c_str());
+		mprintf(_M("%s\n"), MaxTStrFromUtf8(error).data());
+		nlwarning("%s", error.c_str());
 
 		// Error
 		return false;
@@ -395,8 +395,8 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 					icv=getCommonVertex(pPM,idstpatch,isrcpatch,&orderdstvtx);			
 					if (icv==-1)
 					{
-						mprintf (_T("Invalid bind"));
-						nlwarning ("Invalid bind");
+						mprintf(_M("Invalid bind\n"));
+						nlwarning("Invalid bind");
 						return false;
 					}
 					if (idstedge==orderdstvtx) 
@@ -419,7 +419,7 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 						icv=getCommonVertex(pPM,idstpatch,isrcpatch);			
 						if (icv==-1)
 						{
-							mprintf (_T("Invalid bind"));
+							mprintf(_M("Invalid bind\n"));
 							nlwarning ("Invalid bind");
 							return false;
 						}
@@ -436,7 +436,7 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 						icv=getCommonVertex(pPM,idstpatch,isrcpatch);			
 						if (icv==-1)
 						{
-							mprintf (_T("Invalid bind"));
+							mprintf(_M("Invalid bind\n"));
 							nlwarning ("Invalid bind");
 							return false;
 						}
@@ -448,8 +448,8 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 					isrcedge=getEdge(pPM,srcpatch,srcpatch->v[nv],icv);
 					if (isrcedge==-1)
 					{
-						mprintf (_T("Invalid edge"));
-						nlwarning ("Invalid bind");
+						mprintf(_M("Invalid edge\n"));
+						nlwarning("Invalid edge");
 						return false;
 					}
 					// let's fill the dst patch (n is important here... it's the order)
@@ -592,8 +592,8 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 		sym.invert ();
 		if (!CPatchInfo::transform (patchinfo, zoneSymmetry, bank, symmetry, rotate, snapCell, weldThreshold, sym))
 		{
-			mprintf (_T("Can't transform the zone"));
-			nlwarning ("Invalid bind");
+			mprintf(_M("Can't transform the zone\n"));
+			nlwarning("Can't transform the zone");
 			return false;
 		}
 	}
@@ -609,7 +609,7 @@ bool RPatchMesh::exportZone(INode* pNode, PatchMesh* pPM, NL3D::CZone& zone, CZo
 			uint i;
 			for (i=0; i<error.Errors.size (); i++)
 			{
-				mprintf (utf8ToTStr(error.Errors[i]));
+				mprintf(_M("%s\n"), MaxTStrFromUtf8(error.Errors[i]));
 			}
 			return false;
 		}
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/stdafx.cpp b/code/nel/tools/3d/plugin_max/nel_patch_lib/stdafx.cpp
index aa6ca8738..8a8a72179 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_lib/stdafx.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/stdafx.cpp
@@ -14,4 +14,6 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "stdafx.h"
\ No newline at end of file
+#include "stdafx.h"
+
+void nlmax_patch_library_stdafx_dummy() { }
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h
index d0e16bd11..2fa666295 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h
+++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/nel_patch_paint.h
@@ -422,7 +422,7 @@ class PaintPatchMod : public Modifier
 		static bool		automaticLighting;
 		static bool		lockBorders;
 
-		RefResult NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate) { return REF_SUCCEED; }
+		RefResult NotifyRefChanged(NOTIFY_REF_PARAMS) { return REF_SUCCEED; }
 
 		bool includeMeshes;
 		bool preloadTiles;
@@ -481,7 +481,7 @@ class PaintPatchMod : public Modifier
 		void BeginEditParams( IObjParam  *ip, ULONG flags, Animatable *prev );
 		void EndEditParams( IObjParam *ip, ULONG flags, Animatable *next );
 		RefTargetHandle Clone(RemapDir& remap = DefaultRemapDir());
-		const MCHAR *GetObjectName() { return _M("NeL Patch Painter"); }
+		GET_OBJECT_NAME_CONST MCHAR *GetObjectName() { return _M("NeL Patch Painter"); }
 		
 		void RescaleWorldUnits(float f);
 
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp
index 98bc67305..8f3912b0e 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint.cpp
@@ -2839,7 +2839,7 @@ void	mainproc(CScene& scene, CEventListenerAsync& AsyncListener, CEvent3dMouseLi
 		if (GetOpenFileName(&openFile))
 		{
 			// Load the file
-			paintColor.loadBrush (tStrToUtf8(buffer));
+			paintColor.loadBrush (MCharStrToUtf8(buffer));
 			paintColor.setBrushMode (true);
 		}
 	}
@@ -3720,7 +3720,7 @@ void EPM_PaintCMode::DoPaint ()
 					{
 					 	std::string error = NLMISC::toString("Invalid edge '%i' with value '%i' in patch '%i' in PatchMesh", p, mYedge, e);
 					 	nlwarning(error.c_str());
-					 	MessageBox(NULL, utf8ToTStr(error), _T("NeL Patch Painter"), MB_OK | MB_ICONSTOP);
+					 	MessageBox(NULL, MaxTStrFromUtf8(error).data(), _T("NeL Patch Painter"), MB_OK | MB_ICONSTOP);
 					 	return;
 					}
 #if (MAX_RELEASE < 4000)
@@ -3883,8 +3883,8 @@ void EPM_PaintCMode::DoPaint ()
 					}
 					if (patchVoisin.patch!=-1)
 					{
-						std::string first = tStrToUtf8(vectMesh[i].Node->GetName());
-						std::string second = tStrToUtf8(vectMesh[patchVoisin.Mesh].Node->GetName());
+						std::string first = MCharStrToUtf8(vectMesh[i].Node->GetName());
+						std::string second = MCharStrToUtf8(vectMesh[patchVoisin.Mesh].Node->GetName());
 						int rot = (2-((vectMesh[i].Symmetry)?(2-e):e)+((vectMesh[patchVoisin.Mesh].Symmetry)?(2-edgeVoisin):edgeVoisin))&3;
 						int nU = 1 << rpatch->getUIPatch (p).NbTilesU;
 						int nV = 1 << rpatch->getUIPatch (p).NbTilesV;
@@ -3991,7 +3991,7 @@ void EPM_PaintCMode::DoPaint ()
 				}
 				catch (const EStream& stream)
 				{
-					MessageBox (NULL, utf8ToTStr(stream.what()), _T("Error"), MB_OK|MB_ICONEXCLAMATION);
+					MessageBox (NULL, MaxTStrFromUtf8(stream.what()).data(), _T("Error"), MB_OK|MB_ICONEXCLAMATION);
 				}
 			}
 		}
@@ -4063,7 +4063,7 @@ bool loadLigoConfigFile (CLigoConfig& config, Interface& it)
 		if (res)
 		{
 			// Path
-			std::string modulePath = NLMISC::CFile::getPath(tStrToUtf8(sModulePath));
+			std::string modulePath = NLMISC::CFile::getPath(MCharStrToUtf8(sModulePath));
 
 			try
 			{
@@ -4259,8 +4259,8 @@ DWORD WINAPI myThread (LPVOID vData)
 				}
 				else
 				{
-					std::string message = toString("Can't build the zone named %s", tStrToUtf8(pData->VectMesh[i].Node->GetName()).c_str());
-					MessageBox (pData->eproc->ip->GetMAXHWnd(), utf8ToTStr(message), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
+					std::string message = toString("Can't build the zone named %s", MCharStrToUtf8(pData->VectMesh[i].Node->GetName()).c_str());
+					MessageBox (pData->eproc->ip->GetMAXHWnd(), MaxTStrFromUtf8(message).data(), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
 				}
 			}
 
@@ -4362,14 +4362,14 @@ DWORD WINAPI myThread (LPVOID vData)
 		}
 		catch (const EDru& druExcept)
 		{
-			MessageBox (NULL, utf8ToTStr(druExcept.what()), _T("NeL driver utility"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox (NULL, MaxTStrFromUtf8(druExcept.what()).data(), _T("NeL driver utility"), MB_OK|MB_ICONEXCLAMATION);
 		}
 
 		delete pData;
 	}
 	catch (const Exception& e)
 	{
-		MessageBox (NULL, utf8ToTStr(e.what()), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
+		MessageBox (NULL, MaxTStrFromUtf8(e.what()).data(), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
 	}
 
 	return 0;
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp
index 59b7897db..a60ae6ba9 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_ui.cpp
@@ -319,7 +319,7 @@ void getColors (COLORREF *array)
 			DWORD len=4;
 			DWORD type;
 			std::string regName = toString("Color%u", i);
-			RegQueryValueEx (hKey, utf8ToTStr(regName), 0, &type, (LPBYTE)(array+i), &len);
+			RegQueryValueEx (hKey, MaxTStrFromUtf8(regName).data(), 0, &type, (LPBYTE)(array+i), &len);
 		}
 		RegCloseKey (hKey);
 	}
@@ -337,7 +337,7 @@ void setColors (const COLORREF *array)
 		{
 			DWORD len=4;
 			std::string regName = toString("Color%u", i);
-			RegSetValueEx (hKey, utf8ToTStr(regName), 0, REG_DWORD, (LPBYTE)(array+i), 4);
+			RegSetValueEx (hKey, MaxTStrFromUtf8(regName).data(), 0, REG_DWORD, (LPBYTE)(array+i), 4);
 		}
 		RegCloseKey (hKey);
 	}
@@ -412,7 +412,7 @@ void LoadKeyCfg ()
 		if (res)
 		{
 			// Make a new path
-			std::string cfgPath = NLMISC::CFile::getPath(tStrToUtf8(sModulePath)) + "keys.cfg";
+			std::string cfgPath = NLMISC::CFile::getPath(MCharStrToUtf8(sModulePath)) + "keys.cfg";
 	
 			CConfigFile cf;
 
@@ -455,7 +455,7 @@ void LoadVarCfg ()
 		{
 			// Make a new path
 			char cgfPath[256];
-			std::string cfgPath = NLMISC::CFile::getPath(tStrToUtf8(sModulePath)) + "keys.cfg";
+			std::string cfgPath = NLMISC::CFile::getPath(MCharStrToUtf8(sModulePath)) + "keys.cfg";
 	
 			CConfigFile cf;
 
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_vcolor.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_vcolor.cpp
index 7d0a4a3df..a2e8be4b6 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_vcolor.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/paint_vcolor.cpp
@@ -402,7 +402,7 @@ bool CPaintColor::loadBrush (const std::string &brushFileName)
 		{
 			// Error message
 			std::string msg = toString("Can't open the file %s.", brushFileName.c_str());
-			MessageBox ((HWND)CNELU::Driver->getDisplay(), utf8ToTStr(msg), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox((HWND)CNELU::Driver->getDisplay(), MaxTStrFromUtf8(msg).data(), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
 
 			// Return false
 			return false;
@@ -411,7 +411,7 @@ bool CPaintColor::loadBrush (const std::string &brushFileName)
 	catch (const Exception &e)
 	{
 		// Error message
-		MessageBox ((HWND)CNELU::Driver->getDisplay(), utf8ToTStr(e.what()), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
+		MessageBox((HWND)CNELU::Driver->getDisplay(), MaxTStrFromUtf8(e.what()).data(), _T("NeL Painter"), MB_OK|MB_ICONEXCLAMATION);
 
 		// Return false
 		return false;
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_paint/stdafx.cpp b/code/nel/tools/3d/plugin_max/nel_patch_paint/stdafx.cpp
index 62eecad20..7f7ce72f7 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_paint/stdafx.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_patch_paint/stdafx.cpp
@@ -1 +1,3 @@
 #include "stdafx.h" 
+
+void nlmax_patch_painter_stdafx_dummy() { }
diff --git a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.cpp b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.cpp
index 664ec0868..6acec0edd 100644
--- a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.cpp
@@ -483,7 +483,7 @@ void VertexPaint::EndEditParams(IObjParam *ip, ULONG flags, Animatable *next)
 
 
 //From ReferenceMaker 
-RefResult VertexPaint::NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate)
+RefResult VertexPaint::NotifyRefChanged(NOTIFY_REF_PARAMS)
 {
 	return REF_SUCCEED;
 }
diff --git a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.h b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.h
index 7c751899e..991c5a628 100644
--- a/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.h
+++ b/code/nel/tools/3d/plugin_max/nel_vertex_tree_paint/vertex_tree_paint.h
@@ -29,6 +29,7 @@
 #define NL_MAP_ASSERT
 #include <nel/misc/debug.h>
 
+#include "../nel_3dsmax_shared/string_common.h"
 
 #define VERTEX_TREE_PAINT_CLASS_ID	Class_ID(0x40c7005e, 0x2a95082c)
 #define CID_PAINT				(CID_USER+0x439c)
@@ -131,7 +132,7 @@ public:
 		void GetClassName(TSTR& s) { s= TSTR(GetString(IDS_CLASS_NAME)); }  
 		virtual Class_ID ClassID() { return VERTEX_TREE_PAINT_CLASS_ID;}		
 		RefTargetHandle Clone(RemapDir& remap = DefaultRemapDir());
-		const MCHAR *GetObjectName() { return GetString(IDS_CLASS_NAME); }
+		GET_OBJECT_NAME_CONST MCHAR *GetObjectName() { return GetString(IDS_CLASS_NAME); }
 		IOResult Load(ILoad *iload);
 		IOResult Save(ISave *isave);
 		IOResult LoadLocalData(ILoad *iload, LocalModData **pld);
@@ -161,7 +162,7 @@ public:
 		Animatable* SubAnim(int i);
 		TSTR SubAnimName(int i);
 
-		RefResult NotifyRefChanged(const Interval& changeInt,RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate);
+		RefResult NotifyRefChanged(NOTIFY_REF_PARAMS);
 		
 		CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
 		void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
diff --git a/code/nel/tools/3d/plugin_max/tile_utility/rgbadd.cpp b/code/nel/tools/3d/plugin_max/tile_utility/rgbadd.cpp
index 5f512b88e..3c44efb4d 100644
--- a/code/nel/tools/3d/plugin_max/tile_utility/rgbadd.cpp
+++ b/code/nel/tools/3d/plugin_max/tile_utility/rgbadd.cpp
@@ -85,7 +85,7 @@ class RGBAdd: public Texmap {
 		int RemapRefOnLoad(int iref); 
 
 		RefTargetHandle Clone(RemapDir &remap = DefaultRemapDir());
-		RefResult NotifyRefChanged(const Interval &changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate);
+		RefResult NotifyRefChanged(NOTIFY_REF_PARAMS);
 
 		// IO
 		IOResult Save(ISave *isave);
@@ -130,41 +130,41 @@ enum
 
 static ParamBlockDesc2 RGBAdd_param_blk ( RGBAdd_params, _T("parameters"),  0, &maskCD, P_AUTO_CONSTRUCT + P_AUTO_UI, 0, 
 	//rollout
-	IDD_RGBMULT, "RGB Additif Parameters", 0, 0, NULL, 
+	IDD_RGBMULT, _T("RGB Additif Parameters"), 0, 0, NULL, 
 	// params
 	RGBAdd_color1,	 _T("color1"),	TYPE_RGBA,				P_ANIMATABLE,	IDS_DS_COLOR1,
 		p_default,		Color(0,0,0), 
 		p_ui,			TYPE_COLORSWATCH, IDC_MULT_COL1, 
-		p_end,
+		nl_p_end,
 	RGBAdd_color2,	 _T("color2"),	TYPE_RGBA,				P_ANIMATABLE,	IDS_DS_COLOR2,	
 		p_default,		Color(0.5,0.5,0.5), 
 		p_ui,			TYPE_COLORSWATCH, IDC_MULT_COL2, 
-		p_end,
+		nl_p_end,
 	RGBAdd_map1,		_T("map1"),		TYPE_TEXMAP,			P_OWNERS_REF,	IDS_JW_MAP1,
 		p_refno,		1,
 		p_subtexno,		0,		
 		p_ui,			TYPE_TEXMAPBUTTON, IDC_MULT_TEX1,
-		p_end,
+		nl_p_end,
 	RGBAdd_map2,		_T("map2"),		TYPE_TEXMAP,			P_OWNERS_REF,	IDS_JW_MAP2,
 		p_refno,		2,
 		p_subtexno,		1,		
 		p_ui,			TYPE_TEXMAPBUTTON, IDC_MULT_TEX2,
-		p_end,
+		nl_p_end,
 	RGBAdd_map1_on,	_T("map1Enabled"), TYPE_BOOL,			0,				IDS_JW_MAP1ENABLE,
 		p_default,		TRUE,
 		p_ui,			TYPE_SINGLECHEKBOX, IDC_MAPON1,
-		p_end,
+		nl_p_end,
 	RGBAdd_map2_on,	_T("map2Enabled"), TYPE_BOOL,			0,				IDS_JW_MAP2ENABLE,
 		p_default,		TRUE,
 		p_ui,			TYPE_SINGLECHEKBOX, IDC_MAPON2,
-		p_end,
+		nl_p_end,
 	RGBAdd_type, _T("alphaFrom"), TYPE_INT,				0,				IDS_PW_ALPHAFROM,
 		p_default,		2,
 		p_range,		0,	2,
 		p_ui,			TYPE_RADIO, 3, IDC_MULT_ALPHA1, IDC_MULT_ALPHA2, IDC_MULT_ALPHA3,
-		p_end,
+		nl_p_end,
 
-	p_end
+	nl_p_end
 );
 
 
@@ -364,7 +364,7 @@ TSTR RGBAdd::SubAnimName(int i) {
 		}
 	}
 
-RefResult RGBAdd::NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate)
+RefResult RGBAdd::NotifyRefChanged(NOTIFY_REF_PARAMS)
 {
 	switch (message)
 	{
diff --git a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.cpp b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.cpp
index 893f44eea..8110dbab9 100644
--- a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.cpp
+++ b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.cpp
@@ -21,6 +21,8 @@
 #include "nel/misc/file.h"
 #include "../nel_patch_lib/rpo.h"
 
+#include "../nel_3dsmax_shared/string_common.h"
+
 #define TILE_UTILITY_CLASS_ID	Class_ID(0x2301c0, 0x4c156b46)
 
 extern ClassDesc* GetRGBAddDesc();
@@ -192,7 +194,7 @@ static INT_PTR CALLBACK Tile_utilityDlgProc(HWND hWnd, UINT msg, WPARAM wParam,
 						ofn.lpTemplateName=0;
 						if (GetOpenFileName(&ofn))
 						{
-							theTile_utility.Load (tStrToUtf8(sPath));
+							theTile_utility.Load (MCharStrToUtf8(sPath));
 							theTile_utility.SetLand (theTile_utility.Land);
 							theTile_utility.SetupUI ();
 						}
@@ -287,7 +289,7 @@ void Tile_utility::Load (const std::string& path)
 		if (!file.open (path))
 		{
 			std::string tmp = toString("File not found: %s", path.c_str());
-			MessageBox (NULL, utf8ToTStr(tmp), _T("Error.."), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox (NULL, MaxTStrFromUtf8(tmp).data(), _T("Error.."), MB_OK|MB_ICONEXCLAMATION);
 		}
 		else
 		{
@@ -299,7 +301,7 @@ void Tile_utility::Load (const std::string& path)
 	catch (const EStream &stream)
 	{
 		std::string tmp = toString("Error while loading %s:\n\n%s", path.c_str(), stream.what());
-		MessageBox (NULL, utf8ToTStr(tmp), _T("Error.."), MB_OK|MB_ICONEXCLAMATION);
+		MessageBox (NULL, MaxTStrFromUtf8(tmp).data(), _T("Error.."), MB_OK|MB_ICONEXCLAMATION);
 	}
 }
 
@@ -337,7 +339,7 @@ void Tile_utility::SetupUI ()
 		std::string name=Bank.getLand(nLand)->getName();
 		if (hCombo)
 		{
-			SendMessage (hCombo, CB_INSERTSTRING, -1, (LPARAM)utf8ToTStr(name));
+			SendMessage (hCombo, CB_INSERTSTRING, -1, (LPARAM)MaxTStrFromUtf8(name).data());
 		}
 	}
 
@@ -369,7 +371,7 @@ void Tile_utility::SetupUI ()
 				name[0] = upName[0];
 			}
 
-			SetWindowText (hwnd, utf8ToTStr(name));
+			SetWindowText (hwnd, MaxTStrFromUtf8(name).data());
 
 			// Static text
 			TCHAR sTmp[256];
@@ -451,7 +453,7 @@ bool Tile_utility::SetupMaterial () const
 					tex->SetAlphaSource (ALPHA_NONE);
 					tex->SetAlphaAsMono (FALSE);
 					tex->SetAlphaAsRGB (FALSE);
-					tex->SetMapName (utf8ToTStr(Bank.getAbsPath() + tile->getRelativeFileName(CTile::diffuse)));
+					tex->SetMapName (MaxTStrFromUtf8(Bank.getAbsPath() + tile->getRelativeFileName(CTile::diffuse)).data());
 
 					// Assign BitmapTex
 					rgb->SetSubTexmap (0, tex);
@@ -471,7 +473,7 @@ bool Tile_utility::SetupMaterial () const
 					tex->SetAlphaSource (ALPHA_NONE);
 					tex->SetAlphaAsMono (FALSE);
 					tex->SetAlphaAsRGB (FALSE);
-					tex->SetMapName (utf8ToTStr(Bank.getAbsPath() + tile->getRelativeFileName(CTile::additive)));
+					tex->SetMapName (MaxTStrFromUtf8(Bank.getAbsPath() + tile->getRelativeFileName(CTile::additive)).data());
 
 					// Assign BitmapTex
 					rgb->SetSubTexmap (1, tex);
diff --git a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.h b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.h
index 5d5e4e298..9736be511 100644
--- a/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.h
+++ b/code/nel/tools/3d/plugin_max/tile_utility/tile_utility.h
@@ -48,4 +48,6 @@ extern HINSTANCE hInstance;
 
 #define RGBAddClassID (Class_ID(0x5621932, 0x565a6387))
 
+#include "../nel_3dsmax_shared/string_common.h"
+
 #endif // __TILE_UTILITY__H

From 59cf1cf562252db96f453baa16e1d6b52cf934e3 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Sun, 28 Apr 2019 16:48:02 +0800
Subject: [PATCH 18/75] Fix again for Max 2020

---
 .../nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h | 4 ++--
 .../3d/plugin_max/nel_export/nel_export_node_properties.cpp   | 2 +-
 code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp         | 2 +-
 code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h              | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h
index 7b046abbd..72ae6adee 100644
--- a/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h
+++ b/code/nel/tools/3d/plugin_max/nel_3dsmax_shared/string_common.h
@@ -38,7 +38,7 @@ static TSTR MaxTStrFromUtf8(const std::string &src)
 	uc.fromUtf8(src);
 	dst = (const mwchar_t *)uc.c_str();
 #else
-	dst.FromUTF8(source);
+	dst.FromUTF8(src.c_str());
 #endif
 	return dst;
 }
@@ -55,7 +55,7 @@ static std::string MaxTStrToUtf8(const TSTR& src)
 	return uc.toUtf8();
 #endif
 #else
-	return src.ToUTF8();
+	return src.ToUTF8().data();
 #endif
 }
 
diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
index efaa43238..71cde82a5 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
@@ -2493,7 +2493,7 @@ INT_PTR CALLBACK LodDialogCallback (
 
 			// Window text
 			TSTR winName = (*(currentParam->ListNode->begin()))->GetName();
-			winName = TSTR("Node properties (") + winName + ((currentParam->ListNode->size() > 1) ? _M(" ...)") : _M(")"));
+			winName = TSTR(_M("Node properties (")) + winName + ((currentParam->ListNode->size() > 1) ? _M(" ...)") : _M(")"));
 			SetWindowText(hwndDlg, winName.data());
 
 			// Move dialog
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
index 031596932..30d1f929c 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/calc_lm.cpp
@@ -2530,7 +2530,7 @@ bool CExportNel::calculateLM( CMesh::CMeshBuild *pZeMeshBuild, CMeshBase::CMeshB
 		// Add lightmap information in the lightmap log
 		COFile outputLog;
 		if (outputLightmapLog)
-			createLightmapLog(outputLog, gOptions.sExportLighting.c_str(), ucstring(projectName).toUtf8().c_str(), CStr(ZeNode.GetName()).data());
+			createLightmapLog(outputLog, gOptions.sExportLighting.c_str(), ucstring(projectName).toUtf8().c_str(), MaxTStrToUtf8(ZeNode.GetName()).c_str());
 
 		// Update UV coords to Texture space
 		PutFaceUV1InTextureCoord( LightMap.w, LightMap.h, AllFaces.begin(), AllFaces.size() );
diff --git a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h
index 15d477d3b..0f4ead01c 100644
--- a/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h
+++ b/code/nel/tools/3d/plugin_max/nel_patch_lib/rpo.h
@@ -206,7 +206,7 @@ class RPO : public PatchObject
 				? true : PatchObject::IsSubClassOf(classID);
 		}
 		SClass_ID SuperClassID() { return GEOMOBJECT_CLASS_ID; }
-		void GetClassName(TSTR& s) { s = "Rykol Patch Object";}
+		void GetClassName(TSTR& s) { s = _T("Rykol Patch Object");}
 		
 		RefTargetHandle Clone ( RemapDir &remap );
 		RefResult NotifyRefChanged (NOTIFY_REF_PARAMS);

From dbf09dbeef15b1e3f552a8b843186f01d387e87c Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Mon, 29 Apr 2019 03:21:56 +0800
Subject: [PATCH 19/75] Add a comma for multiple nodes

---
 .../3d/plugin_max/nel_export/nel_export_node_properties.cpp     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp b/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
index 71cde82a5..ef5e4c7e7 100644
--- a/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_export/nel_export_node_properties.cpp
@@ -2493,7 +2493,7 @@ INT_PTR CALLBACK LodDialogCallback (
 
 			// Window text
 			TSTR winName = (*(currentParam->ListNode->begin()))->GetName();
-			winName = TSTR(_M("Node properties (")) + winName + ((currentParam->ListNode->size() > 1) ? _M(" ...)") : _M(")"));
+			winName = TSTR(_M("Node properties (")) + winName + ((currentParam->ListNode->size() > 1) ? _M(", ...)") : _M(")"));
 			SetWindowText(hwndDlg, winName.data());
 
 			// Move dialog

From 2eac83a339560349acade9c00381a2e7478c6025 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Mon, 29 Apr 2019 03:26:32 +0800
Subject: [PATCH 20/75] Add Max 8 SDK path to CMake search

---
 code/CMakeModules/Find3dsMaxSDK.cmake | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/code/CMakeModules/Find3dsMaxSDK.cmake b/code/CMakeModules/Find3dsMaxSDK.cmake
index 7bcecb84b..cb00df78e 100644
--- a/code/CMakeModules/Find3dsMaxSDK.cmake
+++ b/code/CMakeModules/Find3dsMaxSDK.cmake
@@ -44,6 +44,7 @@ FIND_PATH(MAXSDK_DIR
   "$ENV{${_pf_x86}}/Autodesk/3ds Max 2009 SDK/maxsdk"
   "$ENV{${_pf_x86}}/Autodesk/3ds Max 2008 SDK/maxsdk"
   "$ENV{${_pf_x86}}/Autodesk/3ds Max 9 SDK/maxsdk"
+  "$ENV{${_pf_x86}}/Autodesk/3dsMax8/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2021 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2020 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2019 SDK/maxsdk"
@@ -59,6 +60,7 @@ FIND_PATH(MAXSDK_DIR
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2009 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 2008 SDK/maxsdk"
   "$ENV{PROGRAMFILES}/Autodesk/3ds Max 9 SDK/maxsdk"
+  "$ENV{PROGRAMFILES}/Autodesk/3dsMax8/maxsdk"
 )
 
 FIND_PATH(MAXSDK_INCLUDE_DIR

From 51e01daa994d04653c9d81f814ead1b15eadacf5 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Mon, 29 Apr 2019 15:36:27 +0300
Subject: [PATCH 21/75] Changed: Remove old luaBeginElement, luaEndElement

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_html.h |    7 -
 code/nel/src/gui/group_html.cpp       | 1643 -------------------------
 2 files changed, 1650 deletions(-)

diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index 6a8760533..cf06a49d0 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -238,8 +238,6 @@ namespace NLGUI
 		int luaInsertText(CLuaState &ls);
 		int luaAddString(CLuaState &ls);
 		int luaAddImage(CLuaState &ls);
-		int luaBeginElement(CLuaState &ls);
-		int luaEndElement(CLuaState &ls);
 		int luaShowDiv(CLuaState &ls);
 		int luaParseHtml(CLuaState &ls);
 		int luaRenderHtml(CLuaState &ls);
@@ -253,8 +251,6 @@ namespace NLGUI
 			REFLECT_LUA_METHOD("insertText", luaInsertText)
 			REFLECT_LUA_METHOD("addString", luaAddString)
 			REFLECT_LUA_METHOD("addImage", luaAddImage)
-			REFLECT_LUA_METHOD("beginElement", luaBeginElement)
-			REFLECT_LUA_METHOD("endElement", luaEndElement)
 			REFLECT_LUA_METHOD("showDiv", luaShowDiv)
 			REFLECT_LUA_METHOD("parseHtml", luaParseHtml)
 			REFLECT_LUA_METHOD("renderHtml", luaRenderHtml)
@@ -736,9 +732,6 @@ namespace NLGUI
 
 	private:
 		friend class CHtmlParser;
-		// TODO: beginElement is overwritten in client quick help class, merge it here?
-		void beginElementDeprecated(uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value);
-		void endElementDeprecated(uint element_number);
 
 		// move src->Children into CurrentHtmlElement.parent.children element
 		void spliceFragment(std::list<CHtmlElement>::iterator src);
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index c40617f50..1f9eb5fd2 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -1503,1578 +1503,6 @@ namespace NLGUI
 		}
 	}
 
-	// ***************************************************************************
-	void CGroupHTML::beginElementDeprecated(uint element_number, const std::vector<bool> &present, const std::vector<const char *> &value)
-	{
-		if (_Browsing)
-		{
-			// Paragraph ?
-			switch(element_number)
-			{
-			case HTML_HTML:
-				if (present[MY_HTML_HTML_STYLE] && value[MY_HTML_HTML_STYLE])
-					_Style.applyRootStyle(value[MY_HTML_HTML_STYLE]);
-
-				_Style.Current = _Style.Root;
-				setBackgroundColor(_Style.Current.BackgroundColor);
-				break;
-			case HTML_HEAD:
-				_ReadingHeadTag = !_IgnoreHeadTag;
-				_IgnoreHeadTag = true;
-				break;
-			case HTML_BASE:
-				if (_ReadingHeadTag && !_IgnoreBaseUrlTag)
-				{
-					if (present[HTML_BASE_HREF] && value[HTML_BASE_HREF])
-					{
-						CUrlParser uri(value[HTML_BASE_HREF]);
-						if (uri.isAbsolute())
-						{
-							_URL = uri.toString();
-							_IgnoreBaseUrlTag = true;
-						}
-					}
-				}
-				break;
-			case HTML_META:
-				if (_ReadingHeadTag)
-				{
-					bool httpEquiv = present[HTML_META_HTTP_EQUIV] && value[HTML_META_HTTP_EQUIV];
-					bool httpContent = present[HTML_META_CONTENT] && value[HTML_META_CONTENT];
-					if (httpEquiv && httpContent)
-					{
-						// only first http-equiv="refresh" should be handled
-						if (_RefreshUrl.empty() && toLower(value[HTML_META_HTTP_EQUIV]) == "refresh")
-						{
-							const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
-							double timeSec = times.thisFrameMs / 1000.0f;
-							string content(value[HTML_META_CONTENT]);
-
-							string::size_type pos = content.find_first_of(";");
-							if (pos == string::npos)
-							{
-								fromString(content, _NextRefreshTime);
-								_RefreshUrl = _URL;
-							}
-							else
-							{
-								fromString(content.substr(0, pos), _NextRefreshTime);
-
-								pos = toLower(content).find("url=");
-								if (pos != string::npos)
-									_RefreshUrl = getAbsoluteUrl(content.substr(pos + 4));
-							}
-
-							_NextRefreshTime += timeSec;
-						}
-					}
-				}
-				break;
-			case HTML_A:
-			{
-				registerAnchorName(MY_HTML_A);
-
-				_Style.pushStyle();
-				_Style.Current.TextColor = LinkColor;
-				_Style.Current.Underlined = true;
-				_Style.Current.GlobalColor = LinkColorGlobalColor;
-				_Style.Current.Width = -1;
-				_Style.Current.Height = -1;
-
-				if (present[HTML_A_STYLE] && value[HTML_A_STYLE])
-					_Style.applyStyle(value[HTML_A_STYLE]);
-
-				_A.push_back(true);
-				_Link.push_back ("");
-				_LinkTitle.push_back("");
-				_LinkClass.push_back("");
-
-				// #fragment works with both ID and NAME so register both
-				if (present[MY_HTML_A_NAME] && value[MY_HTML_A_NAME])
-					_AnchorName.push_back(value[MY_HTML_A_NAME]);
-				if (present[MY_HTML_A_TITLE] && value[MY_HTML_A_TITLE])
-					_LinkTitle.back() = value[MY_HTML_A_TITLE];
-				if (present[MY_HTML_A_CLASS] && value[MY_HTML_A_CLASS])
-					_LinkClass.back() = value[MY_HTML_A_CLASS];
-				if (present[MY_HTML_A_HREF] && value[MY_HTML_A_HREF])
-				{
-					string suri = value[MY_HTML_A_HREF];
-					if(suri.find("ah:") == 0)
-					{
-						if (_TrustedDomain)
-							_Link.back() = suri;
-					}
-					else if (_TrustedDomain && suri[0] == '#' && _LuaHrefHack)
-					{
-						// Direct url (hack for lua beginElement)
-						_Link.back() = suri.substr(1);
-					}
-					else
-					{
-						// convert href from "?key=val" into "http://domain.com/?key=val"
-						_Link.back() = getAbsoluteUrl(suri);
-					}
-				}
-			}
-				break;
-			case HTML_DIV:
-			{
-				_BlockLevelElement.push_back(true);
-				registerAnchorName(MY_HTML_DIV);
-				_Style.pushStyle();
-
-				if (present[MY_HTML_DIV_NAME] && value[MY_HTML_DIV_NAME])
-					_DivName = value[MY_HTML_DIV_NAME];
-
-				string instClass;
-				if (present[MY_HTML_DIV_CLASS] && value[MY_HTML_DIV_CLASS])
-					instClass = value[MY_HTML_DIV_CLASS];
-
-				string style;
-				if (present[MY_HTML_DIV_STYLE] && value[MY_HTML_DIV_STYLE])
-					style = value[MY_HTML_DIV_STYLE];
-
-				if (!style.empty())
-					_Style.applyStyle(style);
-
-				// use generic template system
-				if (_TrustedDomain && !instClass.empty() && instClass == "ryzom-ui-grouptemplate")
-				{
-					string id;
-					if (present[MY_HTML_DIV_ID] && value[MY_HTML_DIV_ID])
-						id = value[MY_HTML_DIV_ID];
-
-					typedef pair<string, string> TTmplParam;
-					vector<TTmplParam> tmplParams;
-					
-					string templateName;
-					if (!style.empty())
-					{
-						TStyle styles = parseStyle(style);
-						TStyle::iterator	it;
-						for (it=styles.begin(); it != styles.end(); it++)
-						{
-							if ((*it).first == "template")
-								templateName = (*it).second;
-							else if ((*it).first == "display" && (*it).second == "inline-block")
-								_BlockLevelElement.back() = false;
-							else
-								tmplParams.push_back(TTmplParam((*it).first, (*it).second));
-						}
-					}
-
-					if (!templateName.empty())
-					{
-						string parentId;
-						bool haveParentDiv = getDiv() != NULL;
-						if (haveParentDiv)
-							parentId = getDiv()->getId();
-						else
-						{
-							if (!_Paragraph)
-								newParagraph (0);
-
-							parentId = _Paragraph->getId();
-						}
-
-						CInterfaceGroup *inst = CWidgetManager::getInstance()->getParser()->createGroupInstance(templateName, parentId+":"+id, tmplParams);
-						if (inst)
-						{
-							inst->setId(parentId+":"+id);
-							inst->updateCoords();
-							if (haveParentDiv)
-							{
-									inst->setParent(getDiv());
-									inst->setParentSize(getDiv());
-									inst->setParentPos(getDiv());
-									inst->setPosRef(Hotspot_TL);
-									inst->setParentPosRef(Hotspot_TL);
-									getDiv()->addGroup(inst);
-
-									_BlockLevelElement.back() = false;
-							}
-							else
-							{
-								getParagraph()->addChild(inst);
-								paragraphChange();
-							}
-							_Divs.push_back(inst);
-						}
-					}
-				}
-
-				if (isBlockLevelElement())
-				{
-					newParagraph(0);
-				}
-			}
-				break;
-			case HTML_FONT:
-			{
-				_Style.pushStyle();
-				if (present[HTML_FONT_COLOR] && value[HTML_FONT_COLOR])
-				{
-					CRGBA color;
-					if (scanHTMLColor(value[HTML_FONT_COLOR], color))
-						_Style.Current.TextColor = color;
-				}
-
-				if (present[HTML_FONT_SIZE] && value[HTML_FONT_SIZE])
-				{
-					uint fontsize;
-					fromString(value[HTML_FONT_SIZE], fontsize);
-					_Style.Current.FontSize = fontsize;
-				}
-			}
-				break;
-			case HTML_BR:
-			{
-				endParagraph();
-
-				// insert zero-width-space (0x200B) to prevent removal of empty lines
-				ucstring tmp;
-				tmp.fromUtf8("\xe2\x80\x8b");
-				addString(tmp);
-			}
-				break;
-			case HTML_BODY:
-				{
-					_Style.pushStyle();
-
-					string style;
-					if (present[HTML_BODY_STYLE] && value[HTML_BODY_STYLE])
-						style = value[HTML_BODY_STYLE];
-
-					if (!style.empty())
-						_Style.applyStyle(style);
-
-					CRGBA bgColor = _Style.Current.BackgroundColor;
-					if (present[HTML_BODY_BGCOLOR] && value[HTML_BODY_BGCOLOR])
-						scanHTMLColor(value[HTML_BODY_BGCOLOR], bgColor);
-
-					if (bgColor != _Style.Current.BackgroundColor)
-						setBackgroundColor(bgColor);
-
-					if (!style.empty())
-					{
-						TStyle styles = parseStyle(style);
-						TStyle::iterator	it;
-
-						it = styles.find("background-repeat");
-						bool repeat = (it != styles.end() && it->second == "1");
-						
-						// Webig only
-						it = styles.find("background-scale");
-						bool scale = (it != styles.end() && it->second == "1");
-
-						it = styles.find("background-image");
-						if (it != styles.end())
-						{
-							string image = it->second;
-							string::size_type texExt = toLower(image).find("url(");
-							// Url image
-							if (texExt != string::npos)
-								// Remove url()
-								image = image.substr(4, image.size()-5);
-							setBackground (image, scale, repeat);
-						}
-					}
-				}
-				break;
-			case HTML_FORM:
-				{
-					// Build the form
-					CGroupHTML::CForm form;
-
-					// Get the action name
-					if (present[HTML_FORM_ACTION] && value[HTML_FORM_ACTION])
-					{
-						form.Action = getAbsoluteUrl(string(value[HTML_FORM_ACTION]));
-					}
-					else
-					{
-						form.Action = _URL;
-					}
-					_Forms.push_back(form);
-				}
-				break;
-			case HTML_H1:
-				{
-					registerAnchorName(MY_HTML_H1);
-					newParagraph(PBeginSpace);
-					_Style.pushStyle();
-					_Style.Current.FontSize = H1FontSize;
-					_Style.Current.TextColor = H1Color;
-					_Style.Current.GlobalColor = H1ColorGlobalColor;
-					if (present[MY_HTML_H1_STYLE] && value[MY_HTML_H1_STYLE])
-						_Style.applyStyle(value[MY_HTML_H1_STYLE]);
-				}
-				break;
-			case HTML_H2:
-				{
-					registerAnchorName(MY_HTML_H2);
-					newParagraph(PBeginSpace);
-					_Style.pushStyle();
-					_Style.Current.FontSize = H2FontSize;
-					_Style.Current.TextColor = H2Color;
-					_Style.Current.GlobalColor = H2ColorGlobalColor;
-					if (present[MY_HTML_H2_STYLE] && value[MY_HTML_H2_STYLE])
-						_Style.applyStyle(value[MY_HTML_H2_STYLE]);
-				}
-				break;
-			case HTML_H3:
-				{
-					registerAnchorName(MY_HTML_H3);
-					newParagraph(PBeginSpace);
-					_Style.pushStyle();
-					_Style.Current.FontSize = H3FontSize;
-					_Style.Current.TextColor = H3Color;
-					_Style.Current.GlobalColor = H3ColorGlobalColor;
-					if (present[MY_HTML_H3_STYLE] && value[MY_HTML_H3_STYLE])
-						_Style.applyStyle(value[MY_HTML_H3_STYLE]);
-				}
-				break;
-			case HTML_H4:
-				{
-					registerAnchorName(MY_HTML_H4);
-					newParagraph(PBeginSpace);
-					_Style.pushStyle();
-					_Style.Current.FontSize = H4FontSize;
-					_Style.Current.TextColor = H4Color;
-					_Style.Current.GlobalColor = H4ColorGlobalColor;
-					if (present[MY_HTML_H4_STYLE] && value[MY_HTML_H4_STYLE])
-						_Style.applyStyle(value[MY_HTML_H4_STYLE]);
-				}
-				break;
-			case HTML_H5:
-				{
-					registerAnchorName(MY_HTML_H5);
-					newParagraph(PBeginSpace);
-					_Style.pushStyle();
-					_Style.Current.FontSize = H5FontSize;
-					_Style.Current.TextColor = H5Color;
-					_Style.Current.GlobalColor = H5ColorGlobalColor;
-					if (present[MY_HTML_H5_STYLE] && value[MY_HTML_H5_STYLE])
-						_Style.applyStyle(value[MY_HTML_H5_STYLE]);
-				}
-				break;
-			case HTML_H6:
-				{
-					registerAnchorName(MY_HTML_H6);
-					newParagraph(PBeginSpace);
-					_Style.pushStyle();
-					_Style.Current.FontSize = H6FontSize;
-					_Style.Current.TextColor = H6Color;
-					_Style.Current.GlobalColor = H6ColorGlobalColor;
-					if (present[MY_HTML_H6_STYLE] && value[MY_HTML_H6_STYLE])
-						_Style.applyStyle(value[MY_HTML_H6_STYLE]);
-				}
-				break;
-			case HTML_IMG:
-				{
-					// Get the string name
-					if (present[MY_HTML_IMG_SRC] && value[MY_HTML_IMG_SRC])
-					{
-						float tmpf;
-						std::string id;
-
-						_Style.pushStyle();
-
-						if (present[MY_HTML_IMG_ID] && value[MY_HTML_IMG_ID])
-							id = value[MY_HTML_IMG_ID];
-
-						if (present[MY_HTML_IMG_WIDTH] && value[MY_HTML_IMG_WIDTH])
-							getPercentage(_Style.Current.Width, tmpf, value[MY_HTML_IMG_WIDTH]);
-						if (present[MY_HTML_IMG_HEIGHT] && value[MY_HTML_IMG_HEIGHT])
-							getPercentage(_Style.Current.Height, tmpf, value[MY_HTML_IMG_HEIGHT]);
-
-						// Get the global color name
-						if (present[MY_HTML_IMG_GLOBAL_COLOR])
-							_Style.Current.GlobalColor = true;
-
-						// width, height from inline css
-						if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE])
-							_Style.applyStyle(value[MY_HTML_IMG_STYLE]);
-
-						// Tooltip
-						const char *tooltip = NULL;
-						// keep "alt" attribute for backward compatibility
-						if (present[MY_HTML_IMG_ALT] && value[MY_HTML_IMG_ALT])
-							tooltip = value[MY_HTML_IMG_ALT];
-						// tooltip
-						if (present[MY_HTML_IMG_TITLE] && value[MY_HTML_IMG_TITLE])
-							tooltip = value[MY_HTML_IMG_TITLE];
-
-						// Mouse over image
-						string overSrc;
-						if (present[MY_HTML_IMG_DATA_OVER_SRC] && value[MY_HTML_IMG_DATA_OVER_SRC])
-						{
-							overSrc = value[MY_HTML_IMG_DATA_OVER_SRC];
-						}
-
-
-						if (getA() && getParent () && getParent ()->getParent())
-						{
-							string params = "name=" + getId() + "|url=" + getLink ();
-							addButton(CCtrlButton::PushButton, id, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC],
-								overSrc, "browse", params.c_str(), tooltip, _Style.Current);
-						}
-						else
-						if (tooltip || !overSrc.empty())
-						{
-							addButton(CCtrlButton::PushButton, id, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC],
-								overSrc, "", "", tooltip, _Style.Current);
-						}
-						else
-						{
-							// Get the option to reload (class==reload)
-							bool reloadImg = false;
-
-							string styleString;
-							if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE])
-								styleString = value[MY_HTML_IMG_STYLE];
-
-							if (!styleString.empty())
-							{
-								TStyle styles = parseStyle(styleString);
-								TStyle::iterator	it;
-
-								it = styles.find("reload");
-								if (it != styles.end() && (*it).second == "1")
-									reloadImg = true;
-							}
-
-							addImage(id, value[MY_HTML_IMG_SRC], reloadImg, _Style.Current);
-						}
-
-						_Style.popStyle();
-					}
-				}
-				break;
-			case HTML_INPUT:
-				// Got one form ?
-				if (!(_Forms.empty()))
-				{
-					// read general property
-					string templateName;
-					string minWidth;
-					string id;
-
-					if (present[MY_HTML_INPUT_ID] && value[MY_HTML_INPUT_ID])
-						id = value[MY_HTML_INPUT_ID];
-
-					// Widget template name
-					if (present[MY_HTML_INPUT_Z_BTN_TMPL] && value[MY_HTML_INPUT_Z_BTN_TMPL])
-						templateName = value[MY_HTML_INPUT_Z_BTN_TMPL];
-					// Input name is the new
-					if (present[MY_HTML_INPUT_Z_INPUT_TMPL] && value[MY_HTML_INPUT_Z_INPUT_TMPL])
-						templateName = value[MY_HTML_INPUT_Z_INPUT_TMPL];
-					// Widget minimal width
-					if (present[MY_HTML_INPUT_Z_INPUT_WIDTH] && value[MY_HTML_INPUT_Z_INPUT_WIDTH])
-						minWidth = value[MY_HTML_INPUT_Z_INPUT_WIDTH];
-
-					// Get the type
-					if (present[MY_HTML_INPUT_TYPE] && value[MY_HTML_INPUT_TYPE])
-					{
-						// by default not inherited, font family defaults to system font
-						_Style.pushStyle();
-						_Style.Current.TextColor = TextColor;
-						_Style.Current.FontSize = TextFontSize;
-						_Style.Current.FontWeight = FONT_WEIGHT_NORMAL;
-						_Style.Current.FontOblique = false;
-						_Style.Current.TextShadow = CStyleParams::STextShadow(true);
-						_Style.Current.Width = -1;
-						_Style.Current.Height = -1;
-
-						// Global color flag
-						if (present[MY_HTML_INPUT_GLOBAL_COLOR])
-							_Style.Current.GlobalColor = true;
-
-						// Tooltip
-						const char *tooltip = NULL;
-						if (present[MY_HTML_INPUT_ALT] && value[MY_HTML_INPUT_ALT])
-							tooltip = value[MY_HTML_INPUT_ALT];
-
-						if (present[MY_HTML_INPUT_STYLE] && value[MY_HTML_INPUT_STYLE])
-							_Style.applyStyle(value[MY_HTML_INPUT_STYLE]);
-
-						string type = toLower(value[MY_HTML_INPUT_TYPE]);
-						if (type == "image")
-						{
-							// The submit button
-							string name;
-							string normal;
-							string pushed;
-							string over;
-							if (present[MY_HTML_INPUT_NAME] && value[MY_HTML_INPUT_NAME])
-								name = value[MY_HTML_INPUT_NAME];
-							if (present[MY_HTML_INPUT_SRC] && value[MY_HTML_INPUT_SRC])
-								normal = value[MY_HTML_INPUT_SRC];
-
-							// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
-							string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=image";
-
-							// Add the ctrl button
-							addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
-								"html_submit_form", param.c_str(), tooltip, _Style.Current);
-						}
-						if (type == "button" || type == "submit")
-						{
-							// The submit button
-							string name;
-							string text;
-							string normal;
-							string pushed;
-							string over;
-
-							string buttonTemplate(!templateName.empty() ? templateName : DefaultButtonGroup );
-							if (present[MY_HTML_INPUT_NAME] && value[MY_HTML_INPUT_NAME])
-								name = value[MY_HTML_INPUT_NAME];
-							if (present[MY_HTML_INPUT_SRC] && value[MY_HTML_INPUT_SRC])
-								normal = value[MY_HTML_INPUT_SRC];
-							if (present[MY_HTML_INPUT_VALUE] && value[MY_HTML_INPUT_VALUE])
-								text = value[MY_HTML_INPUT_VALUE];
-
-							// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
-							string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=submit";
-							if (!text.empty())
-							{
-								// escape AH param separator
-								string tmp = text;
-								while(NLMISC::strFindReplace(tmp, "|", "&#124;"))
-									;
-								param = param + "|submit_button_value=" + tmp;
-							}
-
-							// Add the ctrl button
-							if (!_Paragraph)
-							{
-								newParagraph (0);
-								paragraphChange ();
-							}
-
-							typedef pair<string, string> TTmplParam;
-							vector<TTmplParam> tmplParams;
-							tmplParams.push_back(TTmplParam("id", name));
-							tmplParams.push_back(TTmplParam("onclick", "html_submit_form"));
-							tmplParams.push_back(TTmplParam("onclick_param", param));
-							//tmplParams.push_back(TTmplParam("text", text));
-							tmplParams.push_back(TTmplParam("active", "true"));
-							if (!minWidth.empty())
-								tmplParams.push_back(TTmplParam("wmin", minWidth));
-							CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
-							if (buttonGroup)
-							{
-
-								// Add the ctrl button
-								CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button"));
-								if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
-								if (ctrlButton)
-								{
-									ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
-
-									// Translate the tooltip
-									if (tooltip)
-									{
-										if (CI18N::hasTranslation(tooltip))
-										{
-											ctrlButton->setDefaultContextHelp(CI18N::get(tooltip));
-										}
-										else
-										{
-											ctrlButton->setDefaultContextHelp(ucstring(tooltip));
-										}
-									}
-
-									ctrlButton->setText(ucstring::makeFromUtf8(text));
-
-									setTextButtonStyle(ctrlButton, _Style.Current);
-								}
-								getParagraph()->addChild (buttonGroup);
-								paragraphChange ();
-							}
-						}
-						else if (type == "text")
-						{
-							// Get the string name
-							string name;
-							ucstring ucValue;
-							uint size = 120;
-							uint maxlength = 1024;
-							if (present[MY_HTML_INPUT_NAME] && value[MY_HTML_INPUT_NAME])
-								name = value[MY_HTML_INPUT_NAME];
-							if (present[MY_HTML_INPUT_SIZE] && value[MY_HTML_INPUT_SIZE])
-								fromString(value[MY_HTML_INPUT_SIZE], size);
-							if (present[MY_HTML_INPUT_VALUE] && value[MY_HTML_INPUT_VALUE])
-								ucValue.fromUtf8(value[MY_HTML_INPUT_VALUE]);
-							if (present[MY_HTML_INPUT_MAXLENGTH] && value[MY_HTML_INPUT_MAXLENGTH])
-								fromString(value[MY_HTML_INPUT_MAXLENGTH], maxlength);
-
-							string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup);
-							// Add the editbox
-							CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue, maxlength);
-							if (textArea)
-							{
-								// Add the text area to the form
-								CGroupHTML::CForm::CEntry entry;
-								entry.Name = name;
-								entry.TextArea = textArea;
-								_Forms.back().Entries.push_back (entry);
-							}
-						}
-						else if (type == "checkbox" || type == "radio")
-						{
-							CCtrlButton::EType btnType;
-							string name;
-							string normal;
-							string pushed;
-							string over;
-							ucstring ucValue = ucstring("on");
-							bool checked = false;
-
-							if (type == "radio")
-							{
-								btnType = CCtrlButton::RadioButton;
-								normal = DefaultRadioButtonBitmapNormal;
-								pushed = DefaultRadioButtonBitmapPushed;
-								over = DefaultRadioButtonBitmapOver;
-							}
-							else
-							{
-								btnType = CCtrlButton::ToggleButton;
-								normal = DefaultCheckBoxBitmapNormal;
-								pushed = DefaultCheckBoxBitmapPushed;
-								over = DefaultCheckBoxBitmapOver;
-							}
-
-							if (present[MY_HTML_INPUT_NAME] && value[MY_HTML_INPUT_NAME])
-								name = value[MY_HTML_INPUT_NAME];
-							if (present[MY_HTML_INPUT_SRC] && value[MY_HTML_INPUT_SRC])
-								normal = value[MY_HTML_INPUT_SRC];
-							if (present[MY_HTML_INPUT_VALUE] && value[MY_HTML_INPUT_VALUE])
-								ucValue.fromUtf8(value[MY_HTML_INPUT_VALUE]);
-							checked = (present[MY_HTML_INPUT_CHECKED] && value[MY_HTML_INPUT_CHECKED]);
-
-							// Add the ctrl button
-							CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style.Current);
-							if (checkbox)
-							{
-								if (btnType == CCtrlButton::RadioButton)
-								{
-									// override with 'id' because radio buttons share same name
-									if (!id.empty())
-										checkbox->setId(id);
-
-									// group together buttons with same name
-									CForm &form = _Forms.back();
-									bool notfound = true;
-									for (uint i=0; i<form.Entries.size(); i++)
-									{
-										if (form.Entries[i].Name == name && form.Entries[i].Checkbox->getType() == CCtrlButton::RadioButton)
-										{
-											checkbox->initRBRefFromRadioButton(form.Entries[i].Checkbox);
-											notfound = false;
-											break;
-										}
-									}
-									if (notfound)
-									{
-										// this will start a new group (initRBRef() would take first button in group container otherwise)
-										checkbox->initRBRefFromRadioButton(checkbox);
-									}
-								}
-
-								checkbox->setPushed (checked);
-
-								// Add the button to the form
-								CGroupHTML::CForm::CEntry entry;
-								entry.Name = name;
-								entry.Value = decodeHTMLEntities(ucValue);
-								entry.Checkbox = checkbox;
-								_Forms.back().Entries.push_back (entry);
-							}
-						}
-						else if (type == "hidden")
-						{
-							if (present[MY_HTML_INPUT_NAME] && value[MY_HTML_INPUT_NAME])
-							{
-								// Get the name
-								string name = value[MY_HTML_INPUT_NAME];
-
-								// Get the value
-								ucstring ucValue;
-								if (present[MY_HTML_INPUT_VALUE] && value[MY_HTML_INPUT_VALUE])
-									ucValue.fromUtf8(value[MY_HTML_INPUT_VALUE]);
-
-								// Add an entry
-								CGroupHTML::CForm::CEntry entry;
-								entry.Name = name;
-								entry.Value = decodeHTMLEntities(ucValue);
-								_Forms.back().Entries.push_back (entry);
-							}
-						}
-
-						_Style.popStyle();
-					}
-				}
-				break;
-			case HTML_SELECT:
-				if (!(_Forms.empty()))
-				{
-					_Style.pushStyle();
-					_Style.Current.Width = -1;
-					_Style.Current.Height = -1;
-
-					// A select box
-					string name;
-					bool multiple = false;
-					sint32 size = 0;
-
-					if (present[HTML_SELECT_NAME] && value[HTML_SELECT_NAME])
-						name = value[HTML_SELECT_NAME];
-					if (present[HTML_SELECT_SIZE] && value[HTML_SELECT_SIZE])
-						fromString(value[HTML_SELECT_SIZE], size);
-					if (present[HTML_SELECT_MULTIPLE] && value[HTML_SELECT_MULTIPLE])
-						multiple = true;
-					if (present[HTML_SELECT_STYLE] && value[HTML_SELECT_STYLE])
-						_Style.applyStyle(value[HTML_SELECT_STYLE]);
-
-					CGroupHTML::CForm::CEntry entry;
-					entry.Name = name;
-					entry.sbMultiple = multiple;
-					if (size > 1 || multiple)
-					{
-						entry.InitialSelection = -1;
-						CGroupMenu *sb = addSelectBox(DefaultFormSelectBoxMenuGroup, name.c_str());
-						if (sb)
-						{
-							if (size < 1)
-								size = 4;
-
-							if (_Style.Current.Width > -1)
-								sb->setMinW(_Style.Current.Width);
-
-							if (_Style.Current.Height > -1)
-								sb->setMinH(_Style.Current.Height);
-
-							sb->setMaxVisibleLine(size);
-							sb->setFontSize(_Style.Current.FontSize);
-						}
-
-						entry.SelectBox = sb;
-					}
-					else
-					{
-						CDBGroupComboBox *cb = addComboBox(DefaultFormSelectGroup, name.c_str());
-						entry.ComboBox = cb;
-
-						if (cb)
-						{
-							// create view text
-							cb->updateCoords();
-							if (cb->getViewText())
-								setTextStyle(cb->getViewText(), _Style.Current);
-						}
-					}
-					_Forms.back().Entries.push_back (entry);
-
-					_Style.popStyle();
-				}
-			break;
-			case HTML_OPTION:
-				// Got one form ?
-				if (!(_Forms.empty()))
-				{
-					if (!_Forms.back().Entries.empty())
-					{
-						// clear the option string
-						_SelectOptionStr.clear();
-
-						std::string optionValue;
-						if (present[HTML_OPTION_VALUE] && value[HTML_OPTION_VALUE])
-							optionValue = value[HTML_OPTION_VALUE];
-						_Forms.back().Entries.back().SelectValues.push_back(optionValue);
-
-						if (present[HTML_OPTION_SELECTED])
-							_Forms.back().Entries.back().InitialSelection = (sint)_Forms.back().Entries.back().SelectValues.size() - 1;
-						if (present[HTML_OPTION_DISABLED])
-							_Forms.back().Entries.back().sbOptionDisabled = (sint)_Forms.back().Entries.back().SelectValues.size() - 1;
-					}
-				}
-				_SelectOption = true;
-			break;
-			case HTML_LI:
-				if (!_UL.empty())
-				{
-					// UL, OL top margin if this is the first LI
-					if (!_LI)
-					{
-						_LI = true;
-						newParagraph(ULBeginSpace);
-					}
-					else
-					{
-						newParagraph(LIBeginSpace);
-					}
-
-					// OL list index can be overridden by <li value="1"> attribute
-					if (present[HTML_LI_VALUE] && value[HTML_LI_VALUE])
-						fromString(value[HTML_LI_VALUE], _UL.back().Value);
-
-					_Style.pushStyle();
-					if (present[HTML_LI_STYLE] && value[HTML_LI_STYLE])
-						_Style.applyStyle(value[HTML_LI_STYLE]);
-
-					ucstring str;
-					str.fromUtf8(_UL.back().getListMarkerText());
-					addString (str);
-
-					sint32 indent = LIIndent;
-					// list-style-type: outside
-					if (_CurrentViewLink)
-					{
-						getParagraph()->setFirstViewIndent(-_CurrentViewLink->getMaxUsedW());
-					}
-
-					flushString ();
-
-					_UL.back().Value++;
-				}
-				break;
-			case HTML_P:
-				{
-					newParagraph(PBeginSpace);
-					_Style.pushStyle();
-					if (present[MY_HTML_P_STYLE] && value[MY_HTML_P_STYLE])
-						_Style.applyStyle(value[MY_HTML_P_STYLE]);
-				}
-				break;
-			case HTML_PRE:
-				{
-					_Style.pushStyle();
-					_Style.Current.FontFamily = "monospace";
-
-					if (present[HTML_PRE_STYLE] && value[HTML_PRE_STYLE])
-						_Style.applyStyle(value[HTML_PRE_STYLE]);
-
-
-					_PRE.push_back(true);
-				}
-				break;
-			case HTML_TABLE:
-				{
-					_Style.pushStyle();
-					registerAnchorName(MY_HTML_TABLE);
-
-					// Get cells parameters
-					getCellsParameters_DEP (MY_HTML_TABLE, false);
-
-					CGroupTable *table = new CGroupTable(TCtorParam());
-					table->BgColor = _CellParams.back().BgColor;
-
-					if (present[MY_HTML_TABLE_WIDTH] && value[MY_HTML_TABLE_WIDTH])
-						getPercentage (table->ForceWidthMin, table->TableRatio, value[MY_HTML_TABLE_WIDTH]);
-					if (present[MY_HTML_TABLE_BORDER] && value[MY_HTML_TABLE_BORDER])
-						fromString(value[MY_HTML_TABLE_BORDER], table->Border);
-					if (present[MY_HTML_TABLE_BORDERCOLOR] && value[MY_HTML_TABLE_BORDERCOLOR])
-						scanHTMLColor(value[MY_HTML_TABLE_BORDERCOLOR], table->BorderColor);
-					if (present[MY_HTML_TABLE_CELLSPACING] && value[MY_HTML_TABLE_CELLSPACING])
-						fromString(value[MY_HTML_TABLE_CELLSPACING], table->CellSpacing);
-					if (present[MY_HTML_TABLE_CELLPADDING] && value[MY_HTML_TABLE_CELLPADDING])
-						fromString(value[MY_HTML_TABLE_CELLPADDING], table->CellPadding);
-					if (present[MY_HTML_TABLE_STYLE] && value[MY_HTML_TABLE_STYLE])
-						_Style.applyStyle(value[MY_HTML_TABLE_STYLE]);
-
-					table->setMarginLeft(getIndent());
-					addHtmlGroup (table, 0);
-
-					_Tables.push_back(table);
-
-					// Add a cell pointer
-					_Cells.push_back(NULL);
-					_TR.push_back(false);
-					_Indent.push_back(0);
-				}
-				break;
-			case HTML_TH:
-				// TH is similar to TD, just different font style
-			case HTML_TD:
-				{
-					// Get cells parameters
-					getCellsParameters_DEP (MY_HTML_TD, true);
-
-					_Style.pushStyle();
-					if (element_number == HTML_TH)
-					{
-						_Style.Current.FontWeight = FONT_WEIGHT_BOLD;
-						// center if not specified otherwise. TD/TH present/value arrays have same indices
-						if (!(present[MY_HTML_TD_ALIGN] && value[MY_HTML_TD_ALIGN]))
-							_CellParams.back().Align = CGroupCell::Center;
-					}
-
-					if (present[MY_HTML_TD_STYLE] && value[MY_HTML_TD_STYLE])
-						_Style.applyStyle(value[MY_HTML_TD_STYLE]);
-
-					CGroupTable *table = getTable();
-					if (table)
-					{
-						if (!_Cells.empty())
-						{
-							_Cells.back() = new CGroupCell(CViewBase::TCtorParam());
-							string style;
-							if (present[MY_HTML_TD_STYLE] && value[MY_HTML_TD_STYLE])
-								style = value[MY_HTML_TD_STYLE];
-
-							// Set the cell parameters
-							if (!style.empty())
-							{
-								TStyle styles = parseStyle(style);
-								TStyle::iterator	it;
-
-								it = styles.find("background-repeat");
-								_Cells.back()->setTextureTile(it != styles.end());
-
-								// Webig only
-								it = styles.find("background-scale");
-								_Cells.back()->setTextureScale(it != styles.end());
-
-								it = styles.find("background-image");
-								if (it != styles.end())
-								{
-									string image = (*it).second;
-									string::size_type texExt = toLower(image).find("url(");
-									// Url image
-									if (texExt != string::npos)
-									{
-										// Remove url()
-										image = image.substr(4, image.size()-5);
-										addImageDownload(image, _Cells.back());
-									// Image in BNP
-									}
-									else
-									{
-										_Cells.back()->setTexture(image);
-									}
-								}
-							}
-
-							if (present[MY_HTML_TD_COLSPAN] && value[MY_HTML_TD_COLSPAN])
-								fromString(value[MY_HTML_TD_COLSPAN], _Cells.back()->ColSpan);
-							if (present[MY_HTML_TD_ROWSPAN] && value[MY_HTML_TD_ROWSPAN])
-								fromString(value[MY_HTML_TD_ROWSPAN], _Cells.back()->RowSpan);
-
-							_Cells.back()->BgColor = _CellParams.back().BgColor;
-							_Cells.back()->Align = _CellParams.back().Align;
-							_Cells.back()->VAlign = _CellParams.back().VAlign;
-							_Cells.back()->LeftMargin = _CellParams.back().LeftMargin;
-							_Cells.back()->NoWrap = _CellParams.back().NoWrap;
-							_Cells.back()->ColSpan = std::max(1, _Cells.back()->ColSpan);
-							_Cells.back()->RowSpan = std::max(1, _Cells.back()->RowSpan);
-
-							float temp;
-							if (present[MY_HTML_TD_WIDTH] && value[MY_HTML_TD_WIDTH])
-								getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, value[MY_HTML_TD_WIDTH]);
-							if (present[MY_HTML_TD_HEIGHT] && value[MY_HTML_TD_HEIGHT])
-								getPercentage (_Cells.back()->Height, temp, value[MY_HTML_TD_HEIGHT]);
-
-							_Cells.back()->NewLine = getTR();
-							table->addChild (_Cells.back());
-
-							// reusing indent pushed by table
-							_Indent.back() = 0;
-
-							newParagraph(TDBeginSpace);
-							// indent is already 0, getParagraph()->setMarginLeft(0); // maybe setIndent(0) if LI is using one
-
-							// Reset TR flag
-							if (!_TR.empty())
-								_TR.back() = false;
-						}
-					}
-				}
-				break;
-			case HTML_TEXTAREA:
-				_Style.pushStyle();
-				_PRE.push_back(true);
-
-				// not inherited by default, font family defaults to system font
-				_Style.Current.TextColor = TextColor;
-				_Style.Current.FontWeight = FONT_WEIGHT_NORMAL;
-				_Style.Current.FontOblique = false;
-				_Style.Current.FontSize = TextFontSize;
-				_Style.Current.TextShadow = CStyleParams::STextShadow(true);
-				_Style.Current.Width = -1;
-				_Style.Current.Height = -1;
-
-				if (present[MY_HTML_TEXTAREA_STYLE] && value[MY_HTML_TEXTAREA_STYLE])
-					_Style.applyStyle(value[MY_HTML_TEXTAREA_STYLE]);
-
-				// Got one form ?
-				if (!(_Forms.empty()))
-				{
-					// read general property
-					string templateName;
-
-					// Widget template name
-					if (present[MY_HTML_TEXTAREA_Z_INPUT_TMPL] && value[MY_HTML_TEXTAREA_Z_INPUT_TMPL])
-						templateName = value[MY_HTML_TEXTAREA_Z_INPUT_TMPL];
-
-					// Get the string name
-					_TextAreaName.clear();
-					_TextAreaRow = 1;
-					_TextAreaCols = 10;
-					_TextAreaContent.clear();
-					_TextAreaMaxLength = 1024;
-					if (present[MY_HTML_TEXTAREA_NAME] && value[MY_HTML_TEXTAREA_NAME])
-						_TextAreaName = value[MY_HTML_TEXTAREA_NAME];
-					if (present[MY_HTML_TEXTAREA_ROWS] && value[MY_HTML_TEXTAREA_ROWS])
-						fromString(value[MY_HTML_TEXTAREA_ROWS], _TextAreaRow);
-					if (present[MY_HTML_TEXTAREA_COLS] && value[MY_HTML_TEXTAREA_COLS])
-						fromString(value[MY_HTML_TEXTAREA_COLS], _TextAreaCols);
-					if (present[MY_HTML_TEXTAREA_MAXLENGTH] && value[MY_HTML_TEXTAREA_MAXLENGTH])
-						fromString(value[MY_HTML_TEXTAREA_MAXLENGTH], _TextAreaMaxLength);
-
-					_TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup;
-					_TextArea = true;
-				}
-				break;
-			case HTML_TITLE:
-				{
-					if(!_TitlePrefix.empty())
-						_TitleString = _TitlePrefix + " - ";
-					else
-						_TitleString.clear();
-					_Title = true;
-				}
-				break;
-			case HTML_I:
-				{
-					_Localize = true;
-				}
-				break;
-			case HTML_TR:
-				{
-					// Get cells parameters
-					getCellsParameters_DEP (MY_HTML_TR, true);
-
-					// Set TR flag
-					if (!_TR.empty())
-						_TR.back() = true;
-
-					_Style.pushStyle();
-					if (present[MY_HTML_TR_STYLE] && value[MY_HTML_TR_STYLE])
-						_Style.applyStyle(value[MY_HTML_TR_STYLE]);
-				}
-				break;
-			case HTML_UL:
-				if (_UL.empty())
-					_UL.push_back(HTMLOListElement(1, "disc"));
-				else if (_UL.size() == 1)
-					_UL.push_back(HTMLOListElement(1, "circle"));
-				else
-					_UL.push_back(HTMLOListElement(1, "square"));
-				// if LI is already present
-				_LI = _UL.size() > 1 || _DL.size() > 1;
-				_Indent.push_back(getIndent() + ULIndent);
-				endParagraph();
-
-				_Style.pushStyle();
-				if (present[HTML_UL_STYLE] && value[HTML_UL_STYLE])
-					_Style.applyStyle(value[HTML_UL_STYLE]);
-				break;
-			case HTML_OBJECT:
-				_ObjectType.clear();
-				_ObjectData.clear();
-				_ObjectMD5Sum.clear();
-				_ObjectAction.clear();
-				if (present[HTML_OBJECT_TYPE] && value[HTML_OBJECT_TYPE])
-					_ObjectType = value[HTML_OBJECT_TYPE];
-				if (present[HTML_OBJECT_DATA] && value[HTML_OBJECT_DATA])
-					_ObjectData = value[HTML_OBJECT_DATA];
-				if (present[HTML_OBJECT_ID] && value[HTML_OBJECT_ID])
-					_ObjectMD5Sum = value[HTML_OBJECT_ID];
-				if (present[HTML_OBJECT_STANDBY] && value[HTML_OBJECT_STANDBY])
-					_ObjectAction = value[HTML_OBJECT_STANDBY];
-				_Object = true;
-
-				break;
-			case HTML_SPAN:
-				{
-					_Style.pushStyle();
-
-					if (present[MY_HTML_SPAN_STYLE] && value[MY_HTML_SPAN_STYLE])
-						_Style.applyStyle(value[MY_HTML_SPAN_STYLE]);
-				}
-				break;
-			case HTML_DEL:
-				{
-					_Style.pushStyle();
-					_Style.Current.StrikeThrough = true;
-				}
-				break;
-			case HTML_U:
-				{
-					_Style.pushStyle();
-					_Style.Current.Underlined = true;
-				}
-				break;
-			case HTML_EM:
-				{
-					_Style.pushStyle();
-					_Style.Current.FontOblique = true;
-				}
-				break;
-			case HTML_STRONG:
-				{
-					_Style.pushStyle();
-					_Style.Current.FontWeight = FONT_WEIGHT_BOLD;
-				}
-				break;
-			case HTML_SMALL:
-				{
-					_Style.pushStyle();
-					_Style.Current.FontSize = _Style.getFontSizeSmaller();
-				}
-				break;
-			case HTML_STYLE:
-			case HTML_SCRIPT:
-				_IgnoreText = true;
-				break;
-			case HTML_DL:
-				{
-					_DL.push_back(HTMLDListElement());
-					_LI = _DL.size() > 1 || !_UL.empty();
-					endParagraph();
-					_Style.pushStyle();
-					if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
-						_Style.applyStyle(value[HTML_GEN_STYLE]);
-				}
-				break;
-			case HTML_DT:
-				if (!_DL.empty())
-				{
-					// close if still open
-					if (_DL.back().DD)
-					{
-						_DL.back().DD = false;
-						popIfNotEmpty(_Indent);
-						_Style.popStyle();
-					}
-
-					// close if still open
-					if (_DL.back().DT)
-						_Style.popStyle();
-
-					_DL.back().DT = true;
-
-					_Style.pushStyle();
-					_Style.Current.FontWeight = FONT_WEIGHT_BOLD;
-					if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
-						_Style.applyStyle(value[HTML_GEN_STYLE]);
-
-					if (!_LI)
-					{
-						_LI = true;
-						newParagraph(ULBeginSpace);
-					}
-					else
-					{
-						newParagraph(LIBeginSpace);
-					}
-				}
-				break;
-			case HTML_DD:
-				if (!_DL.empty())
-				{
-					// if there was no closing tag for <dt>, then remove <dt> style
-					if (_DL.back().DT)
-					{
-						_DL.back().DT = false;
-						_Style.popStyle();
-					}
-
-					if (_DL.back().DD)
-					{
-						_DL.back().DD = false;
-						_Style.popStyle();
-						popIfNotEmpty(_Indent);
-					}
-
-					_DL.back().DD = true;
-					_Indent.push_back(getIndent() + ULIndent);
-
-					_Style.pushStyle();
-					if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
-						_Style.applyStyle(value[HTML_GEN_STYLE]);
-
-					if (!_LI)
-					{
-						_LI = true;
-						newParagraph(ULBeginSpace);
-					}
-					else
-					{
-						newParagraph(LIBeginSpace);
-					}
-				}
-				break;
-			case HTML_OL:
-				{
-					_Style.pushStyle();
-					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];
-					if (present[HTML_OL_STYLE] && value[HTML_OL_STYLE])
-						_Style.applyStyle(value[HTML_OL_STYLE]);
-
-					_UL.push_back(HTMLOListElement(start, type));
-					// if LI is already present
-					_LI = _UL.size() > 1 || _DL.size() > 1;
-					_Indent.push_back(getIndent() + ULIndent);
-					endParagraph();
-				}
-				break;
-			case HTML_HR:
-				{
-					newParagraph(0);
-
-					CInterfaceGroup *sep = CWidgetManager::getInstance()->getParser()->createGroupInstance("html_hr", "", NULL, 0);
-					if (sep)
-					{
-						_Style.pushStyle();
-						_Style.Current.TextColor = CRGBA(120, 120, 120, 255);
-						_Style.Current.Height = -1;
-						_Style.Current.Width = -1;
-
-						if (present[HTML_HR_STYLE] && value[HTML_HR_STYLE])
-							_Style.applyStyle(value[HTML_HR_STYLE]);
-
-						CViewBitmap *bitmap = dynamic_cast<CViewBitmap*>(sep->getView("hr"));
-						if (bitmap)
-						{
-							bitmap->setColor(_Style.Current.TextColor);
-							if (_Style.Current.Width > 0)
-							{
-								clamp(_Style.Current.Width, 1, 32000);
-								bitmap->setW(_Style.Current.Width);
-								bitmap->setSizeRef(CInterfaceElement::none);
-							}
-							if (_Style.Current.Height > 0)
-							{
-								clamp(_Style.Current.Height, 1, 1000);
-								bitmap->setH(_Style.Current.Height);
-							}
-						}
-
-						getParagraph()->addChild(sep);
-						endParagraph();
-
-						_Style.popStyle();
-					}
-				}
-				break;
-			}
-		}
-	}
-
-	// ***************************************************************************
-
-	void CGroupHTML::endElementDeprecated(uint element_number)
-	{
-		if (_Browsing)
-		{
-			// Paragraph ?
-			switch(element_number)
-			{
-			case HTML_HEAD:
-				_ReadingHeadTag = false;
-				break;
-			case HTML_BODY:
-				_Style.popStyle();
-				break;
-			case HTML_FONT:
-				_Style.popStyle();
-			break;
-			case HTML_A:
-				_Style.popStyle();
-				popIfNotEmpty (_A);
-				popIfNotEmpty (_Link);
-				popIfNotEmpty (_LinkTitle);
-				popIfNotEmpty (_LinkClass);
-				break;
-			case HTML_H1:
-			case HTML_H2:
-			case HTML_H3:
-			case HTML_H4:
-			case HTML_H5:
-			case HTML_H6:
-				_Style.popStyle();
-				endParagraph();
-				break;
-			case HTML_P:
-				_Style.popStyle();
-				endParagraph();
-				break;
-			case HTML_PRE:
-				_Style.popStyle();
-				popIfNotEmpty (_PRE);
-				break;
-			case HTML_DIV:
-				_Style.popStyle();
-				if (isBlockLevelElement())
-				{
-					endParagraph();
-				}
-				_DivName.clear();
-				popIfNotEmpty (_Divs);
-				popIfNotEmpty (_BlockLevelElement);
-				break;
-
-			case HTML_TABLE:
-				_Style.popStyle();
-				popIfNotEmpty (_CellParams);
-				popIfNotEmpty (_TR);
-				popIfNotEmpty (_Cells);
-				popIfNotEmpty (_Tables);
-				popIfNotEmpty (_Indent);
-				endParagraph();
-				// Add a cell
-				break;
-			case HTML_TH:
-				// no break;
-			case HTML_TD:
-				_Style.popStyle();
-				popIfNotEmpty (_CellParams);
-				if (!_Cells.empty())
-					_Cells.back() = NULL;
-				break;
-			case HTML_TR:
-				_Style.popStyle();
-				popIfNotEmpty (_CellParams);
-				break;
-			case HTML_TEXTAREA:
-				{
-					_TextArea = false;
-					if (!(_Forms.empty()))
-					{
-						CInterfaceGroup *textArea = addTextArea (_TextAreaTemplate, _TextAreaName.c_str (), _TextAreaRow, _TextAreaCols, true, _TextAreaContent, _TextAreaMaxLength);
-						if (textArea)
-						{
-							// Add the text area to the form
-							CGroupHTML::CForm::CEntry entry;
-							entry.Name = _TextAreaName;
-							entry.TextArea = textArea;
-							_Forms.back().Entries.push_back (entry);
-						}
-					}
-
-					_Style.popStyle();
-					popIfNotEmpty (_PRE);
-				}
-				break;
-			case HTML_TITLE:
-				{
-					_Title = false;
-
-					// Get the parent container
-					setTitle (_TitleString);
-				}
-				break;
-			case HTML_SELECT:
-				{
-					_SelectOption = false;
-					if (!(_Forms.empty()))
-					{
-						if (!_Forms.back().Entries.empty())
-						{
-							CDBGroupComboBox *cb = _Forms.back().Entries.back().ComboBox;
-							if (cb)
-							{
-								cb->setSelectionNoTrigger(_Forms.back().Entries.back().InitialSelection);
-								cb->setW(cb->evalContentWidth() + 16);
-							}
-						}
-					}
-				}
-				break;
-			case HTML_OPTION:
-				if (!(_Forms.empty()) && !(_Forms.back().Entries.empty()))
-				{
-					// insert the parsed text into the select control
-					CDBGroupComboBox *cb = _Forms.back().Entries.back().ComboBox;
-					if (cb)
-					{
-						uint lineIndex = cb->getNumTexts();
-						cb->addText(_SelectOptionStr);
-						if (_Forms.back().Entries.back().sbOptionDisabled == lineIndex)
-						{
-							cb->setGrayed(lineIndex, true);
-						}
-					}
-					else
-					{
-						CGroupMenu *sb = _Forms.back().Entries.back().SelectBox;
-						if (sb)
-						{
-							uint lineIndex = sb->getNumLine();
-							sb->addLine(_SelectOptionStr, "", "");
-
-							if (_Forms.back().Entries.back().sbOptionDisabled == lineIndex)
-							{
-								sb->setGrayedLine(lineIndex, true);
-							}
-							else
-							{
-								// create option line checkbox, CGroupMenu is taking ownership of the checbox
-								CInterfaceGroup *ig = CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_checkbox", "", NULL, 0);
-								if (ig)
-								{
-									CCtrlButton *cb = dynamic_cast<CCtrlButton *>(ig->getCtrl("b"));
-									if (cb)
-									{
-										if (_Forms.back().Entries.back().sbMultiple)
-										{
-											cb->setType(CCtrlButton::ToggleButton);
-											cb->setTexture(DefaultCheckBoxBitmapNormal);
-											cb->setTexturePushed(DefaultCheckBoxBitmapPushed);
-											cb->setTextureOver(DefaultCheckBoxBitmapOver);
-										}
-										else
-										{
-											cb->setType(CCtrlButton::RadioButton);
-											cb->setTexture(DefaultRadioButtonBitmapNormal);
-											cb->setTexturePushed(DefaultRadioButtonBitmapPushed);
-											cb->setTextureOver(DefaultRadioButtonBitmapOver);
-
-											if (_Forms.back().Entries.back().sbRBRef == NULL)
-												_Forms.back().Entries.back().sbRBRef = cb;
-
-											cb->initRBRefFromRadioButton(_Forms.back().Entries.back().sbRBRef);
-										}
-
-										cb->setPushed(_Forms.back().Entries.back().InitialSelection == lineIndex);
-										sb->setUserGroupLeft(lineIndex, ig);
-									}
-									else
-									{
-										nlwarning("Failed to get 'b' element from 'menu_checkbox' template");
-										delete ig;
-									}
-								}
-							}
-						}
-					}
-				}
-				break;
-			case HTML_I:
-				{
-					_Localize = false;
-				}
-				break;
-			case HTML_OL:
-			case HTML_UL:
-				if (!_UL.empty())
-				{
-					endParagraph();
-					_Style.popStyle();
-					popIfNotEmpty(_UL);
-					popIfNotEmpty(_Indent);
-				}
-				break;
-			case HTML_LI:
-				{
-					_Style.popStyle();
-				}
-				break;
-			case HTML_DL:
-				if (!_DL.empty())
-				{
-					endParagraph();
-
-					// unclosed DT
-					if (_DL.back().DT)
-					{
-						_Style.popStyle();
-					}
-
-					// unclosed DD
-					if (_DL.back().DD)
-					{
-						popIfNotEmpty(_Indent);
-						_Style.popStyle();
-					}
-
-					popIfNotEmpty (_DL);
-					_Style.popStyle();
-				}
-				break;
-			case HTML_DT:
-				if (!_DL.empty())
-				{
-					if (_DL.back().DT)
-						_Style.popStyle();
-					_DL.back().DT = false;
-				}
-				break;
-			case HTML_DD:
-				if (!_DL.empty())
-				{
-					// parser will process two DD in a row as nested when first DD is not closed
-					if (_DL.back().DD)
-					{
-						_DL.back().DD = false;
-						popIfNotEmpty(_Indent);
-						_Style.popStyle();
-					}
-				}
-				break;
-			case HTML_SPAN:
-				_Style.popStyle();
-				break;
-			case HTML_DEL:
-				_Style.popStyle();
-				break;
-			case HTML_U:
-				_Style.popStyle();
-				break;
-			case HTML_EM:
-				_Style.popStyle();
-				break;
-			case HTML_STRONG:
-				_Style.popStyle();
-				break;
-			case HTML_SMALL:
-				_Style.popStyle();
-				break;
-			case HTML_STYLE:
-			case HTML_SCRIPT:
-				_IgnoreText = false;
-				break;
-			case HTML_OBJECT:
-				if (_TrustedDomain)
-				{
-					if (_ObjectType=="application/ryzom-data")
-					{
-						if (!_ObjectData.empty())
-						{
-							if (addBnpDownload(_ObjectData, _ObjectAction, _ObjectScript, _ObjectMD5Sum))
-							{
-								CLuaManager::getInstance().executeLuaScript("\nlocal __ALLREADYDL__=true\n"+_ObjectScript, true);
-							}
-							_ObjectScript.clear();
-						}
-					}
-					_Object = false;
-				}
-				break;
-			}
-		}
-	}
-
 	// ***************************************************************************
 	NLMISC_REGISTER_OBJECT(CViewBase, CGroupHTML, std::string, "html");
 
@@ -6237,77 +4665,6 @@ namespace NLGUI
 		return 0;
 	}
 
-	// ***************************************************************************
-	// @deprecated
-	int CGroupHTML::luaBeginElement(CLuaState &ls)
-	{
-		nlwarning("Deprecated luaBeginElement on url '%s'", _URL.c_str());
-
-		const char *funcName = "beginElement";
-		CLuaIHM::checkArgCount(ls, funcName, 2);
-		CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
-		CLuaIHM::checkArgType(ls, funcName, 2, LUA_TTABLE);
-
-		uint element_number = (uint)ls.toInteger(1);
-		std::vector<bool> present;
-		std::vector<const char *> value;
-		present.resize(30, false);
-		value.resize(30);
-
-		CLuaObject params;
-		params.pop(ls);
-		uint max_idx = 0;
-
-
-		ENUM_LUA_TABLE(params, it)
-		{
-			if (!it.nextKey().isInteger())
-			{
-				nlwarning("%s : bad key encountered with type %s, integer expected.", funcName, it.nextKey().getTypename());
-				continue;
-			}
-			if (!it.nextValue().isString())
-			{
-				nlwarning("%s : bad value encountered with type %s for key %s, string expected.", funcName, it.nextValue().getTypename(), it.nextKey().toString().c_str());
-				continue;
-			}
-			uint idx = (uint)it.nextKey().toInteger();
-
-			present.insert(present.begin() + (uint)it.nextKey().toInteger(), true);
-
-			string str = it.nextValue().toString();
-			size_t size = str.size() + 1;
-			char * buffer = new char[ size ];
-			strncpy(buffer, str.c_str(), size );
-
-			value.insert(value.begin() + (uint)it.nextKey().toInteger(), buffer);
-		}
-
-		// ingame lua scripts from browser are using <a href="#http://..."> url scheme
-		// reason unknown
-		_LuaHrefHack = true;
-		beginElementDeprecated(element_number, present, value);
-		_LuaHrefHack = false;
-
-		return 0;
-	}
-
-
-	// ***************************************************************************
-	// @deprecated
-	int CGroupHTML::luaEndElement(CLuaState &ls)
-	{
-		const char *funcName = "endElement";
-		CLuaIHM::checkArgCount(ls, funcName, 1);
-		CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
-
-		uint element_number = (uint)ls.toInteger(1);
-		endElementDeprecated(element_number);
-
-		return 0;
-	}
-
-
 	// ***************************************************************************
 	int CGroupHTML::luaShowDiv(CLuaState &ls)
 	{

From 30fb50d0db4e420dc0d4f6323a399db381e6cb15 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Mon, 29 Apr 2019 15:41:59 +0300
Subject: [PATCH 22/75] Changed: Refactor CGroupHTML browse-render flow

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_html.h         |  26 +-
 code/nel/src/gui/group_html.cpp               | 895 ++++++++----------
 .../client/src/interface_v3/lua_ihm_ryzom.cpp |   1 -
 3 files changed, 421 insertions(+), 501 deletions(-)

diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index cf06a49d0..c4a5c8a34 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -113,13 +113,8 @@ namespace NLGUI
 		// Browse error
 		void browseError (const char *msg);
 
-		// stop browse
-		void stopBrowse ();
-
 		bool isBrowsing();
 
-		void clean() { stopBrowse(); updateRefreshButton(); removeContent(); }
-
 		// Update coords
 		void updateCoords();
 
@@ -263,10 +258,10 @@ namespace NLGUI
 
 		// \name callback from libwww
 
-		// Begin of the parsing of a HTML document
+		// Begin of the rendering of a HTML document
 		virtual void beginBuild ();
 
-		// End of the parsing of a HTML document
+		// End of the rendering of a HTML document
 		virtual void endBuild ();
 
 		// A new text block has been parsed
@@ -284,9 +279,6 @@ namespace NLGUI
 		// Add POST params to the libwww list
 		virtual void addHTTPPostParams (SFormFields &formfields, bool trustedDomain);
 
-		// the current request is terminated
-		virtual void requestTerminated();
-
 		// Get Home URL
 		virtual std::string	home();
 
@@ -402,7 +394,6 @@ namespace NLGUI
 
 		// Browsing..
 		bool			_Browsing;
-		bool			_Connecting;
 		double			_TimeoutValue;			// the timeout in seconds
 		double			_ConnectingTimeout;
 		sint			_RedirectsRemaining;
@@ -759,6 +750,7 @@ namespace NLGUI
 			{
 				if (t == ImgType) imgs.push_back(CDataImageDownload(i, style, imagetype));
 			}
+			~CDataDownload();
 
 		public:
 			CCurlWWWData *data;
@@ -772,13 +764,13 @@ namespace NLGUI
 			std::vector<CDataImageDownload> imgs;
 		};
 
-		std::vector<CDataDownload> Curls;
+		std::list<CDataDownload> Curls;
 		CURLM *MultiCurl;
 		int RunningCurls;
 
 		bool startCurlDownload(CDataDownload &download);
-		void finishCurlDownload(CDataDownload &download);
-		void pumpCurlDownloads();
+		void finishCurlDownload(const CDataDownload &download);
+		void pumpCurlQueue();
 
 		void initImageDownload();
 		void checkImageDownload();
@@ -800,9 +792,15 @@ namespace NLGUI
 		// add css file from <link href=".." rel="stylesheet"> to download queue
 		void addStylesheetDownload(std::vector<std::string> links);
 
+		// stop all curl downalods (html and data)
 		void releaseDownloads();
 		void checkDownloads();
 
+		// _CurlWWW download finished
+		void htmlDownloadFinished(bool success, const std::string &error);
+		// images, stylesheets, etc finished downloading
+		void dataDownloadFinished(bool success, const std::string &error, CDataDownload &data);
+
 		// HtmlType download finished
 		void htmlDownloadFinished(const std::string &content, const std::string &type, long code);
 
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 1f9eb5fd2..24baac399 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -72,8 +72,11 @@ using namespace NLMISC;
 
 namespace NLGUI
 {
-	// Uncomment to see the log about image download
-	//#define LOG_DL 1
+
+	// Uncomment nlwarning() to see the log about curl downloads
+	#define LOG_DL(fmt, ...) //nlwarning(fmt, ## __VA_ARGS__)
+	// Uncomment to log curl progess
+	//#define LOG_CURL_PROGRESS 1
 
 	CGroupHTML::SWebOptions CGroupHTML::options;
 
@@ -89,9 +92,7 @@ namespace NLGUI
 			return url;
 		}
 
-	#ifdef LOG_DL
-		nlwarning("HSTS url : '%s', using https", url.c_str());
-	#endif
+		LOG_DL("HSTS url : '%s', using https", url.c_str());
 		uri.scheme = "https";
 
 		return uri.toString();
@@ -243,7 +244,9 @@ namespace NLGUI
 		{
 			if (dltotal > 0 || dlnow > 0 || ultotal > 0 || ulnow > 0)
 			{
-				nlwarning("> dltotal %d, dlnow %d, ultotal %d, ulnow %d, url '%s'", dltotal, dlnow, ultotal, ulnow, me->Url.c_str());
+				#ifdef LOG_CURL_PROGRESS
+				nlwarning("> dltotal %ld, dlnow %ld, ultotal %ld, ulnow %ld, url '%s'", dltotal, dlnow, ultotal, ulnow, me->Url.c_str());
+				#endif
 			}
 		}
 
@@ -251,6 +254,12 @@ namespace NLGUI
 		return 0;
 	}
 
+	CGroupHTML::CDataDownload::~CDataDownload()
+	{
+		delete data;
+		data = NULL;
+	}
+
 	// Check if domain is on TrustedDomain
 	bool CGroupHTML::isTrustedDomain(const string &domain)
 	{
@@ -451,34 +460,32 @@ namespace NLGUI
 		return dest;
 	}
 
-	void CGroupHTML::pumpCurlDownloads()
+	void CGroupHTML::pumpCurlQueue()
 	{
 		if (RunningCurls < options.curlMaxConnections)
 		{
-			for (vector<CDataDownload>::iterator it=Curls.begin(); it<Curls.end(); it++)
+			std::list<CDataDownload>::iterator it=Curls.begin();
+			uint c = 0;
+			while(it != Curls.end() && RunningCurls < options.curlMaxConnections)
 			{
 				if (it->data == NULL)
 				{
-					#ifdef LOG_DL
-					nlwarning("(%s) starting new download '%s'", _Id.c_str(), it->url.c_str());
-					#endif
+					LOG_DL("(%s) starting new download '%s'", _Id.c_str(), it->url.c_str());
 					if (!startCurlDownload(*it))
 					{
+						LOG_DL("(%s) failed to start '%s)'", _Id.c_str(), it->url.c_str());
 						finishCurlDownload(*it);
-						Curls.erase(it);
-						break;
+						it = Curls.erase(it);
+						continue;
 					}
-
-					RunningCurls++;
-					if (RunningCurls >= options.curlMaxConnections)
-						break;
 				}
+
+				++it;
 			}
 		}
-		#ifdef LOG_DL
+
 		if (RunningCurls > 0 || !Curls.empty())
-			nlwarning("(%s) RunningCurls %d, _Curls %d", _Id.c_str(), RunningCurls, Curls.size());
-		#endif
+			LOG_DL("(%s) RunningCurls %d, _Curls %d", _Id.c_str(), RunningCurls, Curls.size());
 	}
 
 	// Add url to MultiCurl queue and return cURL handle
@@ -499,9 +506,7 @@ namespace NLGUI
 
 		if (cache.Expires > currentTime)
 		{
-	#ifdef LOG_DL
-			nlwarning("Cache for (%s) is not expired (%s, expires:%d)", download.url.c_str(), download.dest.c_str(), cache.Expires - currentTime);
-	#endif
+			LOG_DL("Cache for (%s) is not expired (%s, expires:%d)", download.url.c_str(), download.dest.c_str(), cache.Expires - currentTime);
 			return false;
 		}
 
@@ -509,7 +514,9 @@ namespace NLGUI
 
 		// erase the tmp file if exists
 		if (CFile::fileExists(tmpdest))
+		{
 			CFile::deleteFile(tmpdest);
+		}
 
 		FILE *fp = nlfopen (tmpdest, "wb");
 		if (fp == NULL)
@@ -527,6 +534,7 @@ namespace NLGUI
 			nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str());
 			return false;
 		}
+		LOG_DL("curl easy handle %p created for '%s'", curl, download.url.c_str());
 
 		// https://
 		if (toLower(download.url.substr(0, 8)) == "https://")
@@ -569,12 +577,18 @@ namespace NLGUI
 		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
 		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
 
-		curl_multi_add_handle(MultiCurl, curl);
+		CURLMcode ret = curl_multi_add_handle(MultiCurl, curl);
+		if (ret != CURLM_OK)
+		{
+			nlwarning("cURL multi handle %p error %d on '%s'", curl, ret, download.url.c_str());
+			return false;
+		}
 
+		RunningCurls++;
 		return true;
 	}
 
-	void CGroupHTML::finishCurlDownload(CDataDownload &download)
+	void CGroupHTML::finishCurlDownload(const CDataDownload &download)
 	{
 		std::string tmpfile = download.dest + ".tmp";
 
@@ -591,29 +605,27 @@ namespace NLGUI
 					CBitmap::loadSize(tmpfile, w, h);
 					if (w != 0 && h != 0)
 					{
-						bool refresh = false;
-						if (CFile::fileExists(download.dest))
+						// if not tmpfile, then img is already in cache
+						if (CFile::fileExists(tmpfile))
 						{
-							CFile::deleteFile(download.dest);
-							refresh = true;
-						}
+							if (CFile::fileExists(download.dest))
+							{
+								CFile::deleteFile(download.dest);
+							}
 
-						// to reload image on page, the easiest seems to be changing texture
-						// to temp file temporarily. that forces driver to reload texture from disk
-						// ITexture::touch() seem not to do this.
-						if (refresh)
-						{
+							// to reload image on page, the easiest seems to be changing texture
+							// to temp file temporarily. that forces driver to reload texture from disk
+							// ITexture::touch() seem not to do this.
 							// cache was updated, first set texture as temp file
 							for(uint i = 0; i < download.imgs.size(); i++)
 							{
 								setImage(download.imgs[i].Image, tmpfile, download.imgs[i].Type);
 								setImageSize(download.imgs[i].Image, download.imgs[i].Style);
 							}
+
+							CFile::moveFile(download.dest, tmpfile);
 						}
 
-						// move temp to correct cache file
-						CFile::moveFile(download.dest, tmpfile);
-						// set image texture as cache file
 						for(uint i = 0; i < download.imgs.size(); i++)
 						{
 							setImage(download.imgs[i].Image, download.dest, download.imgs[i].Type);
@@ -632,13 +644,14 @@ namespace NLGUI
 			return;
 		}
 
-		if (!tmpfile.empty())
-		{
-			CFile::moveFile(download.dest, tmpfile);
-		}
-
 		if (download.type == StylesheetType)
 		{
+			// no tmpfile if file was already in cache
+			if (CFile::fileExists(tmpfile) && CFile::fileExists(download.dest))
+			{
+				CFile::deleteFile(download.dest);
+				CFile::moveFile(download.dest, tmpfile);
+			}
 			cssDownloadFinished(download.url, download.dest);
 
 			return;
@@ -646,7 +659,33 @@ namespace NLGUI
 
 		if (download.type == BnpType)
 		{
-			CLuaManager::getInstance().executeLuaScript(download.luaScript, true );
+			bool verified = false;
+			// no tmpfile if file was already in cache
+			if (CFile::fileExists(tmpfile))
+			{
+				verified = download.md5sum.empty() || (download.md5sum != getMD5(tmpfile).toString());
+				if (verified)
+				{
+					if (CFile::fileExists(download.dest))
+					{
+						CFile::deleteFile(download.dest);
+					}
+					CFile::moveFile(download.dest, tmpfile);
+				}
+				else
+				{
+					CFile::deleteFile(tmpfile);
+				}
+			}
+			else if (CFile::fileExists(download.dest))
+			{
+				verified = download.md5sum.empty() || (download.md5sum != getMD5(download.dest).toString());
+			}
+
+			std::string script = "\nlocal __CURRENT_WINDOW__ = \""+this->_Id+"\"";
+			script += toString("\nlocal __DOWNLOAD_STATUS__ = %s\n", verified ? "true" : "false");
+			script += download.luaScript;
+			CLuaManager::getInstance().executeLuaScript(script, true );
 
 			return;
 		}
@@ -661,9 +700,7 @@ namespace NLGUI
 
 		// use requested url for local name (cache)
 		string dest = localImageName(url);
-	#ifdef LOG_DL
-		nlwarning("add to download '%s' dest '%s' img %p", finalUrl.c_str(), dest.c_str(), img);
-	#endif
+		LOG_DL("add to download '%s' dest '%s' img %p", finalUrl.c_str(), dest.c_str(), img);
 
 		// Display cached image while downloading new
 		if (type != OverImage && CFile::fileExists(dest))
@@ -673,28 +710,23 @@ namespace NLGUI
 		}
 
 		// Search if we are not already downloading this url.
-		for(uint i = 0; i < Curls.size(); i++)
+		for(std::list<CDataDownload>::iterator it = Curls.begin(); it != Curls.end(); ++it)
 		{
-			if(Curls[i].url == finalUrl)
+			if(it->url == finalUrl)
 			{
-	#ifdef LOG_DL
-				nlwarning("already downloading '%s' img %p", finalUrl.c_str(), img);
-	#endif
-				Curls[i].imgs.push_back(CDataImageDownload(img, style, type));
+				LOG_DL("already downloading '%s' img %p", finalUrl.c_str(), img);
+				it->imgs.push_back(CDataImageDownload(img, style, type));
 				return;
 			}
 		}
 
 		Curls.push_back(CDataDownload(finalUrl, dest, ImgType, img, "", "", style, type));
-
-		pumpCurlDownloads();
+		pumpCurlQueue();
 	}
 
 	void CGroupHTML::initImageDownload()
 	{
-	#ifdef LOG_DL
-		nlwarning("Init Image Download");
-	#endif
+		LOG_DL("Init Image Download");
 
 		string pathName = "cache";
 		if ( ! CFile::isExists( pathName ) )
@@ -716,21 +748,17 @@ namespace NLGUI
 		url = upgradeInsecureUrl(getAbsoluteUrl(url));
 
 		// Search if we are not already downloading this url.
-		for(uint i = 0; i < Curls.size(); i++)
+		for(std::list<CDataDownload>::const_iterator it = Curls.begin(); it != Curls.end(); ++it)
 		{
-			if(Curls[i].url == url)
+			if(it->url == url)
 			{
-	#ifdef LOG_DL
-				nlwarning("already downloading '%s'", url.c_str());
-	#endif
+				LOG_DL("already downloading '%s'", url.c_str());
 				return false;
 			}
 		}
 
 		string dest = localBnpName(url);
-	#ifdef LOG_DL
-		nlwarning("add to download '%s' dest '%s'", url.c_str(), dest.c_str());
-	#endif
+		LOG_DL("add to download '%s' dest '%s'", url.c_str(), dest.c_str());
 
 		// create/delete the local file
 		if (NLMISC::CFile::fileExists(dest))
@@ -748,8 +776,7 @@ namespace NLGUI
 		if (action != "delete")
 		{
 			Curls.push_back(CDataDownload(url, dest, BnpType, NULL, script, md5sum));
-
-			pumpCurlDownloads();
+			pumpCurlQueue();
 		}
 		else
 			return true;
@@ -762,9 +789,7 @@ namespace NLGUI
 		if (!_TrustedDomain)
 			return;
 
-	#ifdef LOG_DL
-		nlwarning("Init Bnp Download");
-	#endif
+		LOG_DL("Init Bnp Download");
 		string pathName = "user";
 		if ( ! CFile::isExists( pathName ) )
 			CFile::createDirectory( pathName );
@@ -782,11 +807,11 @@ namespace NLGUI
 			if (it == _StylesheetQueue.end())
 			{
 				_StylesheetQueue.push_back(url);
-				Curls.push_back(CDataDownload(url, local, StylesheetType, NULL, "", ""));
+				// push to the front of the queue
+				Curls.push_front(CDataDownload(url, local, StylesheetType, NULL, "", ""));
 			}
 		}
-
-		pumpCurlDownloads();
+		pumpCurlQueue();
 	}
 
 	// Call this evenly to check if an element is downloaded and then manage it
@@ -795,212 +820,51 @@ namespace NLGUI
 		//nlassert(_CrtCheckMemory());
 
 		if(Curls.empty() && _CurlWWW == NULL)
+		{
 			return;
+		}
 
 		int NewRunningCurls = 0;
 		while(CURLM_CALL_MULTI_PERFORM == curl_multi_perform(MultiCurl, &NewRunningCurls))
 		{
-	#ifdef LOG_DL
-			nlwarning("more to do now %d - %d curls", NewRunningCurls, Curls.size());
-	#endif
+			LOG_DL("more to do now %d - %d curls", NewRunningCurls, Curls.size());
 		}
-		if(NewRunningCurls < RunningCurls)
+
+		LOG_DL("NewRunningCurls:%d, RunningCurls:%d", NewRunningCurls, RunningCurls);
+
+		// check which downloads are done
+		CURLMsg *msg;
+		int msgs_left;
+		while ((msg = curl_multi_info_read(MultiCurl, &msgs_left)))
 		{
-			// some download are done, callback them
-	#ifdef LOG_DL
-			nlwarning ("new %d old %d", NewRunningCurls, RunningCurls);
-	#endif
-			// check msg
-			CURLMsg *msg;
-			int msgs_left;
-			while ((msg = curl_multi_info_read(MultiCurl, &msgs_left)))
+			LOG_DL("> (%s) msgs_left %d", _Id.c_str(), msgs_left);
+			if (msg->msg == CURLMSG_DONE)
 			{
-	#ifdef LOG_DL
-				nlwarning("> (%s) msgs_left %d", _Id.c_str(), msgs_left);
-	#endif
-				if (msg->msg == CURLMSG_DONE)
+				if (_CurlWWW && _CurlWWW->Request && _CurlWWW->Request == msg->easy_handle)
 				{
-					if (_CurlWWW && _CurlWWW->Request && _CurlWWW->Request == msg->easy_handle)
+					std::string error;
+					bool success = msg->data.result == CURLE_OK;
+					if (!success)
 					{
-						CURLcode res = msg->data.result;
-						long code;
-						curl_easy_getinfo(_CurlWWW->Request, CURLINFO_RESPONSE_CODE, &code);
-	#ifdef LOG_DL
-						nlwarning("(%s) web transfer '%p' completed with status %d, http %d, url (len %d) '%s'", _Id.c_str(), _CurlWWW->Request, res, code, _CurlWWW->Url.size(), _CurlWWW->Url.c_str());
-	#endif
-						// save HSTS header from all requests regardless of HTTP code
-						if (res == CURLE_OK && _CurlWWW->hasHSTSHeader())
-						{
-							CUrlParser uri(_CurlWWW->Url);
-							CStrictTransportSecurity::getInstance()->setFromHeader(uri.host, _CurlWWW->getHSTSHeader());
-						}
-
-						if (res != CURLE_OK)
-						{
-							std::string err;
-							err = "Connection failed with cURL error: ";
-							err += curl_easy_strerror(res);
-							err += "\nURL '" + _CurlWWW->Url + "'";
-							browseError(err.c_str());
-						}
-						else
-						if ((code >= 301 && code <= 303) || code == 307 || code == 308)
-						{
-							if (_RedirectsRemaining < 0)
-							{
-								browseError(string("Redirect limit reached : " + _URL).c_str());
-							}
-							else
-							{
-								receiveCookies(_CurlWWW->Request, _DocumentDomain, _TrustedDomain);
-
-								// redirect, get the location and try browse again
-								// we cant use curl redirection because 'addHTTPGetParams()' must be called on new destination
-								std::string location(_CurlWWW->getLocationHeader());
-								if (!location.empty())
-								{
-	#ifdef LOG_DL
-									nlwarning("(%s) request (%d) redirected to (len %d) '%s'", _Id.c_str(), _RedirectsRemaining, location.size(), location.c_str());
-	#endif
-									location = getAbsoluteUrl(location);
-									// throw away this handle and start with new one (easier than reusing)
-									requestTerminated();
-
-									_PostNextTime = false;
-									_RedirectsRemaining--;
-
-									doBrowse(location.c_str());
-								}
-								else
-								{
-									browseError(string("Request was redirected, but location was not set : "+_URL).c_str());
-								}
-							}
-						}
-						else
-						{
-							receiveCookies(_CurlWWW->Request, _DocumentDomain, _TrustedDomain);
-
-							_RedirectsRemaining = DEFAULT_RYZOM_REDIRECT_LIMIT;
-
-							if ( (code < 200 || code >= 300) )
-							{
-								browseError(string("Connection failed (curl code " + toString((sint32)res) + ")\nhttp code " + toString((sint32)code) + ")\nURL '" + _CurlWWW->Url + "'").c_str());
-							}
-							else
-							{
-								char *ch;
-								std::string contentType;
-								res = curl_easy_getinfo(_CurlWWW->Request, CURLINFO_CONTENT_TYPE, &ch);
-								if (res == CURLE_OK && ch != NULL)
-								{
-									contentType = ch;
-								}
-
-								htmlDownloadFinished(_CurlWWW->Content, contentType, code);
-							}
-							requestTerminated();
-						}
-
-						continue;
+						error = curl_easy_strerror(msg->data.result);
 					}
-
-					for (vector<CDataDownload>::iterator it=Curls.begin(); it<Curls.end(); it++)
+					LOG_DL("html download finished with curl code %d (%s)", (sint)msg->msg, error.c_str());
+					htmlDownloadFinished(success, error);
+				}
+				else
+				{
+					for(std::list<CDataDownload>::iterator it = Curls.begin(); it != Curls.end(); ++it)
 					{
 						if(it->data && it->data->Request == msg->easy_handle)
 						{
-							CURLcode res = msg->data.result;
-							long r;
-							curl_easy_getinfo(it->data->Request, CURLINFO_RESPONSE_CODE, &r);
-							fclose(it->fp);
-
-							CUrlParser uri(it->url);
-							if (!uri.host.empty())
-								receiveCookies(it->data->Request, uri.host, isTrustedDomain(uri.host));
-	#ifdef LOG_DL
-							nlwarning("(%s) transfer '%p' completed with status %d, http %d, url (len %d) '%s'", _Id.c_str(), it->data->Request, res, r, it->url.size(), it->url.c_str());
-	#endif
-							curl_multi_remove_handle(MultiCurl, it->data->Request);
-
-							// save HSTS header from all requests regardless of HTTP code
-							if (res == CURLE_OK && it->data->hasHSTSHeader())
+							std::string error;
+							bool success = msg->data.result == CURLE_OK;
+							if (!success)
 							{
-								CStrictTransportSecurity::getInstance()->setFromHeader(uri.host, it->data->getHSTSHeader());
+								error = curl_easy_strerror(msg->data.result);
 							}
-
-							std::string tmpfile = it->dest + ".tmp";
-							if(res != CURLE_OK || r < 200 || r >= 300 || (!it->md5sum.empty() && (it->md5sum != getMD5(tmpfile).toString())))
-							{
-								if (it->redirects < DEFAULT_RYZOM_REDIRECT_LIMIT && ((r >= 301 && r <= 303) || r == 307 || r == 308))
-								{
-									std::string location(it->data->getLocationHeader());
-									if (!location.empty())
-									{
-										CUrlParser uri(location);
-										if (!uri.isAbsolute())
-										{
-											uri.inherit(it->url);
-											location = uri.toString();
-										}
-
-										it->url = location;
-										it->fp = NULL;
-
-										// release CCurlWWWData
-										delete it->data;
-										it->data = NULL;
-
-										it->redirects++;
-	#ifdef LOG_DL
-										nlwarning("Redirect '%s'", location.c_str());
-	#endif
-										// keep the request in queue
-										continue;
-									}
-									else
-										nlwarning("Redirected to empty url '%s'", it->url.c_str());
-								}
-								else
-								{
-									if (it->redirects >= DEFAULT_RYZOM_REDIRECT_LIMIT)
-										nlwarning("Redirect limit reached for '%s'", it->url.c_str());
-
-									CFile::deleteFile(tmpfile);
-
-									// 304 Not Modified
-									if (res == CURLE_OK && r == 304)
-									{
-										CHttpCacheObject obj;
-										obj.Expires = it->data->getExpires();
-										obj.Etag = it->data->getEtag();
-										obj.LastModified = it->data->getLastModified();
-
-										CHttpCache::getInstance()->store(it->dest, obj);
-									}
-									else
-									{
-										// 404, 500, etc
-										if (CFile::fileExists(it->dest))
-											CFile::deleteFile(it->dest);
-									}
-
-									finishCurlDownload(*it);
-								}
-							}
-							else
-							{
-								CHttpCacheObject obj;
-								obj.Expires = it->data->getExpires();
-								obj.Etag = it->data->getEtag();
-								obj.LastModified = it->data->getLastModified();
-
-								CHttpCache::getInstance()->store(it->dest, obj);
-
-								finishCurlDownload(*it);
-							}
-
-							// release CCurlWWWData
-							delete it->data;
+							LOG_DL("data download finished with curl code %d (%s)", (sint)msg->msg, error.c_str());
+							dataDownloadFinished(success, error, *it);
 
 							Curls.erase(it);
 							break;
@@ -1011,30 +875,51 @@ namespace NLGUI
 		}
 
 		RunningCurls = NewRunningCurls;
-
-		pumpCurlDownloads();
+		pumpCurlQueue();
 	}
 
 
 	void CGroupHTML::releaseDownloads()
 	{
-	#ifdef LOG_DL
-		nlwarning("Release Downloads");
-	#endif
+		LOG_DL("Release Downloads");
+
+		if (_CurlWWW)
+		{
+			LOG_DL("(%s) stop html url '%s'", _Id.c_str(), _CurlWWW->Url.c_str());
+			if (MultiCurl)
+				curl_multi_remove_handle(MultiCurl, _CurlWWW->Request);
+
+			delete _CurlWWW;
+			_CurlWWW = NULL;
+		}
 
 		// remove all queued and already started downloads
-		for (uint i = 0; i < Curls.size(); ++i)
+		for(std::list<CDataDownload>::iterator it = Curls.begin(); it != Curls.end(); ++it)
 		{
-			if (Curls[i].data)
+			if (it->data)
 			{
+				LOG_DL("(%s) stop data url '%s'", _Id.c_str(), it->url.c_str());
 				if (MultiCurl)
-					curl_multi_remove_handle(MultiCurl, Curls[i].data->Request);
+				{
+					curl_multi_remove_handle(MultiCurl, it->data->Request);
+				}
 
-				// release CCurlWWWData
-				delete Curls[i].data;
+				// close and remove temp file
+				if (it->fp)
+				{
+					fclose(it->fp);
+
+					if (CFile::fileExists(it->dest + ".tmp"))
+					{
+						CFile::deleteFile(it->dest + ".tmp");
+					}
+				}
 			}
 		}
 		Curls.clear();
+
+		// also clear css queue as it depends on Curls
+		_StylesheetQueue.clear();
 	}
 
 	class CGroupListAdaptor : public CInterfaceGroup
@@ -1062,20 +947,6 @@ namespace NLGUI
 	template<class A> void popIfNotEmpty(A &vect) { if(!vect.empty()) vect.pop_back(); }
 
 	// ***************************************************************************
-
-	void CGroupHTML::beginBuild ()
-	{
-		if (_Browsing)
-		{
-			_Connecting = false;
-
-			removeContent ();
-		}
-		else
-			nlwarning("_Browsing = FALSE");
-	}
-
-
 	TStyle CGroupHTML::parseStyle (const string &str_styles)
 	{
 		TStyle styles;
@@ -1162,44 +1033,6 @@ namespace NLGUI
 			_AnchorName.push_back(value[prefix##_ID]); \
 	}
 
-	// ***************************************************************************
-
-	#define getCellsParameters_DEP(prefix,inherit) \
-	{\
-		CGroupHTML::CCellParams cellParams; \
-		if (!_CellParams.empty() && inherit) \
-		{ \
-			cellParams = _CellParams.back(); \
-		} \
-		if (present[prefix##_BGCOLOR] && value[prefix##_BGCOLOR]) \
-			scanHTMLColor(value[prefix##_BGCOLOR], cellParams.BgColor); \
-		if (present[prefix##_L_MARGIN] && value[prefix##_L_MARGIN]) \
-			fromString(value[prefix##_L_MARGIN], cellParams.LeftMargin); \
-		if (present[prefix##_NOWRAP]) \
-			cellParams.NoWrap = true; \
-		if (present[prefix##_ALIGN] && value[prefix##_ALIGN]) \
-		{ \
-			string align = toLower(value[prefix##_ALIGN]); \
-			if (align == "left") \
-				cellParams.Align = CGroupCell::Left; \
-			if (align == "center") \
-				cellParams.Align = CGroupCell::Center; \
-			if (align == "right") \
-				cellParams.Align = CGroupCell::Right; \
-		} \
-		if (present[prefix##_VALIGN] && value[prefix##_VALIGN]) \
-		{ \
-			string align = toLower(value[prefix##_VALIGN]); \
-			if (align == "top") \
-				cellParams.VAlign = CGroupCell::Top; \
-			if (align == "middle") \
-				cellParams.VAlign = CGroupCell::Middle; \
-			if (align == "bottom") \
-				cellParams.VAlign = CGroupCell::Bottom; \
-		} \
-		_CellParams.push_back (cellParams); \
-	}
-
 	// ***************************************************************************
 	void CGroupHTML::beginElement (CHtmlElement &elm)
 	{
@@ -1531,7 +1364,6 @@ namespace NLGUI
 		_BrowseNextTime = false;
 		_PostNextTime = false;
 		_Browsing = false;
-		_Connecting = false;
 		_CurrentViewLink = NULL;
 		_CurrentViewImage = NULL;
 		_Indent.clear();
@@ -1627,12 +1459,6 @@ namespace NLGUI
 		*/
 		_GroupHtmlByUID.erase(_GroupHtmlUID);
 
-		// stop browsing
-		stopBrowse (); // NB : we don't call updateRefreshButton here, because :
-					   // 1) it is useless,
-					   // 2) it crashed before when it called getElementFromId (that didn't work when a master group was being removed...). Btw it should work now
-					   //     this is why the call to 'updateRefreshButton' has been removed from stopBrowse
-
 		clearContext();
 		releaseDownloads();
 
@@ -2626,24 +2452,7 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::doBrowse(const char *url, bool force)
 	{
-		// Stop previous browse
-		if (_Browsing)
-		{
-			// Clear all the context
-			clearContext();
-
-			_Browsing = false;
-			updateRefreshButton();
-
-	#ifdef LOG_DL
-			nlwarning("(%s) *** ALREADY BROWSING, break first", _Id.c_str());
-	#endif
-		}
-
-	#ifdef LOG_DL
-		nlwarning("(%s) Browsing URL : '%s'", _Id.c_str(), url);
-	#endif
-
+		LOG_DL("(%s) Browsing URL : '%s'", _Id.c_str(), url);
 
 		CUrlParser uri(url);
 		if (!uri.hash.empty())
@@ -2667,7 +2476,6 @@ namespace NLGUI
 
 		// go
 		_URL = uri.toString();
-		_Connecting = false;
 		_BrowseNextTime = true;
 
 		// if a BrowseTree is bound to us, try to select the node that opens this URL (auto-locate)
@@ -2690,6 +2498,8 @@ namespace NLGUI
 
 	void CGroupHTML::browseError (const char *msg)
 	{
+		releaseDownloads();
+
 		// Get the list group from CGroupScrollText
 		removeContent();
 		newParagraph(0);
@@ -2701,30 +2511,17 @@ namespace NLGUI
 		if(!_TitlePrefix.empty())
 			setTitle (_TitlePrefix);
 
-		stopBrowse ();
 		updateRefreshButton();
+		invalidateCoords();
 	}
 
 	// ***************************************************************************
 
 	bool CGroupHTML::isBrowsing()
 	{
-		return _Browsing;
-	}
-
-
-	void CGroupHTML::stopBrowse ()
-	{
-	#ifdef LOG_DL
-		nlwarning("*** STOP BROWSE (%s)", _Id.c_str());
-	#endif
-
-		// Clear all the context
-		clearContext();
-
-		_Browsing = false;
-
-		requestTerminated();
+		return _BrowseNextTime || _PostNextTime || _RenderNextTime ||
+			_Browsing || _WaitingForStylesheet ||
+			_CurlWWW ||  !Curls.empty();
 	}
 
 	// ***************************************************************************
@@ -3357,8 +3154,6 @@ namespace NLGUI
 
 	void CGroupHTML::clearContext()
 	{
-		_CurrentHTMLElement = NULL;
-		_CurrentHTMLNextSibling = NULL;
 		_Paragraph = NULL;
 		_PRE.clear();
 		_Indent.clear();
@@ -3373,6 +3168,7 @@ namespace NLGUI
 		_TR.clear();
 		_Forms.clear();
 		_Groups.clear();
+		_Divs.clear();
 		_Anchors.clear();
 		_AnchorName.clear();
 		_CellParams.clear();
@@ -3384,33 +3180,15 @@ namespace NLGUI
 		_IgnoreHeadTag = false;
 		_IgnoreBaseUrlTag = false;
 
-		// reset style
-		resetCssStyle();
-
-		// TR
-
 		paragraphChange ();
 
 		// clear the pointer to the current image download since all the button are deleted
-	#ifdef LOG_DL
-		nlwarning("Clear pointers to %d curls", Curls.size());
-	#endif
-		for(uint i = 0; i < Curls.size(); i++)
-		{
-			Curls[i].imgs.clear();
-		}
+		LOG_DL("Clear pointers to %d curls", Curls.size());
 
-		// remove download that are still queued
-		for (vector<CDataDownload>::iterator it=Curls.begin(); it<Curls.end(); )
+		// remove image refs from downloads
+		for(std::list<CDataDownload>::iterator it = Curls.begin(); it != Curls.end(); ++it)
 		{
-			if (it->data == NULL) {
-	#ifdef LOG_DL
-		nlwarning("Remove waiting curl download (%s)", it->url.c_str());
-	#endif
-				it = Curls.erase(it);
-			} else {
-				++it;
-			}
+			it->imgs.clear();
 		}
 	}
 
@@ -3694,14 +3472,12 @@ namespace NLGUI
 			_NextRefreshTime = 0;
 		}
 
-		if (_Connecting)
+		if (_CurlWWW)
 		{
-			// Check timeout if needed
+			// still transfering html page
 			if (_TimeoutValue != 0 && _ConnectingTimeout <= ( times.thisFrameMs / 1000.0f ) )
 			{
 				browseError(("Connection timeout : "+_URL).c_str());
-
-				_Connecting = false;
 			}
 		}
 		else
@@ -3719,7 +3495,6 @@ namespace NLGUI
 		if (_BrowseNextTime || _PostNextTime)
 		{
 			// Set timeout
-			_Connecting = true;
 			_ConnectingTimeout = ( times.thisFrameMs / 1000.0f ) + _TimeoutValue;
 
 			// freeze form buttons
@@ -3878,6 +3653,9 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::doBrowseLocalFile(const std::string &uri)
 	{
+		releaseDownloads();
+		updateRefreshButton();
+
 		std::string filename;
 		if (toLower(uri).find("file:/") == 0)
 		{
@@ -3888,19 +3666,11 @@ namespace NLGUI
 			filename = uri;
 		}
 
-	#if LOG_DL
-		nlwarning("browse local file '%s'", filename.c_str());
-	#endif
+		LOG_DL("browse local file '%s'", filename.c_str());
 
 		_TrustedDomain = true;
 		_DocumentDomain = "localhost";
 
-		// Stop previous browse, remove content
-		stopBrowse ();
-
-		_Browsing = true;
-		updateRefreshButton();
-
 		CIFile in;
 		if (in.open(filename))
 		{
@@ -3927,10 +3697,8 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::doBrowseRemoteUrl(std::string url, const std::string &referer, bool doPost, const SFormFields &formfields)
 	{
-		// Stop previous request and remove content
-		stopBrowse ();
-
-		_Browsing = true;
+		// stop all downloads from previous page
+		releaseDownloads();
 		updateRefreshButton();
 
 		// Reset the title
@@ -3941,10 +3709,8 @@ namespace NLGUI
 
 		url = upgradeInsecureUrl(url);
 
-	#if LOG_DL
-		nlwarning("(%s) browse url (trusted=%s) '%s', referer='%s', post='%s', nb form values %d",
+		LOG_DL("(%s) browse url (trusted=%s) '%s', referer='%s', post='%s', nb form values %d",
 				_Id.c_str(), (_TrustedDomain ? "true" :"false"), url.c_str(), referer.c_str(), (doPost ? "true" : "false"), formfields.Values.size());
-	#endif
 
 		if (!MultiCurl)
 		{
@@ -3994,9 +3760,7 @@ namespace NLGUI
 		if (!referer.empty())
 		{
 			curl_easy_setopt(curl, CURLOPT_REFERER, referer.c_str());
-	#ifdef LOG_DL
-			nlwarning("(%s) set referer '%s'", _Id.c_str(), referer.c_str());
-	#endif
+			LOG_DL("(%s) set referer '%s'", _Id.c_str(), referer.c_str());
 		}
 
 		if (doPost)
@@ -4042,7 +3806,7 @@ namespace NLGUI
 		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NLGUI::curlDataCallback);
 		curl_easy_setopt(curl, CURLOPT_WRITEDATA, _CurlWWW);
 
-	#if LOG_DL
+	#ifdef LOG_CURL_PROGRESS
 		// progress callback
 		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
 		curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, NLGUI::curlProgressCallback);
@@ -4059,14 +3823,192 @@ namespace NLGUI
 		int NewRunningCurls = 0;
 		curl_multi_perform(MultiCurl, &NewRunningCurls);
 		RunningCurls++;
+
+		_RedirectsRemaining = DEFAULT_RYZOM_REDIRECT_LIMIT;
 	}
 
 	// ***************************************************************************
+	void CGroupHTML::htmlDownloadFinished(bool success, const std::string &error)
+	{
+		if (!success)
+		{
+			std::string err;
+			err = "Connection failed with cURL error: ";
+			err += error;
+			err += "\nURL '" + _CurlWWW->Url + "'";
+			browseError(err.c_str());
+			return;
+		}
+
+		// save HSTS header from all requests regardless of HTTP code
+		if (_CurlWWW->hasHSTSHeader())
+		{
+			CUrlParser uri(_CurlWWW->Url);
+			CStrictTransportSecurity::getInstance()->setFromHeader(uri.host, _CurlWWW->getHSTSHeader());
+		}
+
+		receiveCookies(_CurlWWW->Request, _DocumentDomain, _TrustedDomain);
+
+		long code;
+		curl_easy_getinfo(_CurlWWW->Request, CURLINFO_RESPONSE_CODE, &code);
+		LOG_DL("(%s) web transfer '%p' completed with http code %d, url (len %d) '%s'", _Id.c_str(), _CurlWWW->Request, code, _CurlWWW->Url.size(), _CurlWWW->Url.c_str());
+
+		if ((code >= 301 && code <= 303) || code == 307 || code == 308)
+		{
+			if (_RedirectsRemaining < 0)
+			{
+				browseError(string("Redirect limit reached : " + _URL).c_str());
+				return;
+			}
+
+			// redirect, get the location and try browse again
+			// we cant use curl redirection because 'addHTTPGetParams()' must be called on new destination
+			std::string location(_CurlWWW->getLocationHeader());
+			if (location.empty())
+			{
+				browseError(string("Request was redirected, but location was not set : "+_URL).c_str());
+				return;
+			}
+
+			LOG_DL("(%s) request (%d) redirected to (len %d) '%s'", _Id.c_str(), _RedirectsRemaining, location.size(), location.c_str());
+			location = getAbsoluteUrl(location);
+
+			_PostNextTime = false;
+			_RedirectsRemaining--;
+
+			doBrowse(location.c_str());
+		}
+		else if ( (code < 200 || code >= 300) )
+		{
+			// catches 304 not modified, but html is not in cache anyway
+			browseError(string("Connection failed\nhttp code " + toString((sint32)code) + ")\nURL '" + _CurlWWW->Url + "'").c_str());
+			return;
+		}
+
+		char *ch;
+		std::string contentType;
+		CURLcode res = curl_easy_getinfo(_CurlWWW->Request, CURLINFO_CONTENT_TYPE, &ch);
+		if (res == CURLE_OK && ch != NULL)
+		{
+			contentType = ch;
+		}
+
+		htmlDownloadFinished(_CurlWWW->Content, contentType, code);
+
+		// clear curl handler
+		if (MultiCurl)
+		{
+			curl_multi_remove_handle(MultiCurl, _CurlWWW->Request);
+		}
+
+		delete _CurlWWW;
+		_CurlWWW = NULL;
+
+		// refresh button uses _CurlWWW. refresh button may stay disabled if
+		// there is no css files to download and page is rendered before _CurlWWW is freed
+		updateRefreshButton();
+	}
+
+	void CGroupHTML::dataDownloadFinished(bool success, const std::string &error, CDataDownload &data)
+	{
+		fclose(data.fp);
+
+		CUrlParser uri(data.url);
+		if (!uri.host.empty())
+		{
+			receiveCookies(data.data->Request, uri.host, isTrustedDomain(uri.host));
+		}
+
+		long code = -1;
+		curl_easy_getinfo(data.data->Request, CURLINFO_RESPONSE_CODE, &code);
+
+		LOG_DL("(%s) transfer '%p' completed with http code %d, url (len %d) '%s'", _Id.c_str(), data.data->Request, code, data.url.size(), data.url.c_str());
+		curl_multi_remove_handle(MultiCurl, data.data->Request);
+
+		// save HSTS header from all requests regardless of HTTP code
+		if (success)
+		{
+			if (data.data->hasHSTSHeader())
+			{
+				CStrictTransportSecurity::getInstance()->setFromHeader(uri.host, data.data->getHSTSHeader());
+			}
+
+			// 2XX success, 304 Not Modified
+			if ((code >= 200 && code <= 204) || code == 304)
+			{
+				CHttpCacheObject obj;
+				obj.Expires = data.data->getExpires();
+				obj.Etag = data.data->getEtag();
+				obj.LastModified = data.data->getLastModified();
+
+				CHttpCache::getInstance()->store(data.dest, obj);
+				std::string tmpfile = data.dest + ".tmp";
+				if (code == 304 && CFile::fileExists(tmpfile))
+				{
+					CFile::deleteFile(tmpfile);
+				}
+			}
+			else if ((code >= 301 && code <= 303) || code == 307 || code == 308)
+			{
+				if (data.redirects < DEFAULT_RYZOM_REDIRECT_LIMIT)
+				{
+					std::string location(data.data->getLocationHeader());
+					if (!location.empty())
+					{
+						CUrlParser uri(location);
+						if (!uri.isAbsolute())
+						{
+							uri.inherit(data.url);
+							location = uri.toString();
+						}
+
+						// push same request in the front of the queue
+						// cache filename is based of original url
+						Curls.push_front(data);
+						// clear old request state
+						Curls.front().data = NULL;
+						Curls.front().fp = NULL;
+						Curls.front().url = location;
+						Curls.front().redirects++;
+
+						LOG_DL("Redirect '%s'", location.c_str());
+						// no finished callback called, so cleanup old temp
+						std::string tmpfile = data.dest + ".tmp";
+						if (CFile::fileExists(tmpfile))
+						{
+							CFile::deleteFile(tmpfile);
+						}
+						return;
+					}
+
+					nlwarning("Redirected to empty url '%s'", data.url.c_str());
+				}
+				else
+				{
+					nlwarning("Redirect limit reached for '%s'", data.url.c_str());
+				}
+			}
+			else
+			{
+				nlwarning("HTTP request failed with code [%d] for '%s'\n",code, data.url.c_str());
+				// 404, 500, etc
+				if (CFile::fileExists(data.dest))
+				{
+					CFile::deleteFile(data.dest);
+				}
+			}
+		}
+		else
+		{
+			nlwarning("DATA download failed '%s', error '%s'", data.url.c_str(), error.c_str());
+		}
+
+		finishCurlDownload(data);
+	}
+
 	void CGroupHTML::htmlDownloadFinished(const std::string &content, const std::string &type, long code)
 	{
-	#ifdef LOG_DL
-		nlwarning("(%s) HTML download finished, content length %d, type '%s', code %d", _Id.c_str(), content.size(), type.c_str(), code);
-	#endif
+		LOG_DL("(%s) HTML download finished, content length %d, type '%s', code %d", _Id.c_str(), content.size(), type.c_str(), code);
 
 		// create <html> markup for image downloads
 		if (type.find("image/") == 0 && !content.empty())
@@ -4078,9 +4020,7 @@ namespace NLGUI
 				out.open(dest);
 				out.serialBuffer((uint8 *)(content.c_str()), content.size());
 				out.close();
-	#ifdef LOG_DL
-				nlwarning("(%s) image saved to '%s', url '%s'", _Id.c_str(), dest.c_str(), _URL.c_str());
-	#endif
+				LOG_DL("(%s) image saved to '%s', url '%s'", _Id.c_str(), dest.c_str(), _URL.c_str());
 			}
 			catch(...) { }
 
@@ -4094,9 +4034,6 @@ namespace NLGUI
 			_LuaScript = "\nlocal __CURRENT_WINDOW__=\""+this->_Id+"\" \n"+content;
 			CLuaManager::getInstance().executeLuaScript(_LuaScript, true);
 			_LuaScript.clear();
-			
-			_Browsing = false;
-			_Connecting = false;
 
 			// disable refresh button
 			clearRefresh();
@@ -4112,7 +4049,7 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local)
 	{
-		// remove from queue
+		// remove file from download queue
 		std::vector<std::string>::iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url);
 		if (it != _StylesheetQueue.end())
 		{
@@ -4134,36 +4071,23 @@ namespace NLGUI
 			// waiting for stylesheets to finish downloading
 			return;
 		}
+		_WaitingForStylesheet = false;
 
 		//TGameTime renderStart = CTime::getLocalTime();
 
-		_Browsing = true;
-		_WaitingForStylesheet = false;
+		// clear previous state and page
+		beginBuild();
+		removeContent();
 
-		// keeps track of currently rendered element
-		_CurrentHTMLElement = NULL;
 		std::list<CHtmlElement>::iterator it = _HtmlDOM.Children.begin();
 		while(it != _HtmlDOM.Children.end())
 		{
 			renderDOM(*it);
 			++it;
 		}
-		_CurrentHTMLElement = NULL;
 
-		// invalidate coords
 		endBuild();
 
-		// set the browser as complete
-		_Browsing = false;
-		updateRefreshButton();
-
-		// check that the title is set, or reset it (in the case the page
-		// does not provide a title)
-		if (_TitleString.empty())
-		{
-			setTitle(_TitlePrefix);
-		}
-
 		//TGameTime renderStop = CTime::getLocalTime();
 		//nlwarning("[%s] render: %.1fms (%s)\n", _Id.c_str(), (renderStop - renderStart), _URL.c_str());
 	}
@@ -4175,7 +4099,7 @@ namespace NLGUI
 		bool success;
 
 		// if we are already rendering, then queue up the next page
-		if (_CurrentHTMLElement)
+		if (_Browsing)
 		{
 			_DocumentHtml = html;
 			_RenderNextTime = true;
@@ -4184,21 +4108,29 @@ namespace NLGUI
 		}
 
 		//
-		_Browsing = true;
 		_DocumentUrl = _URL;
 		_DocumentHtml = html;
 		_NextRefreshTime = 0;
 		_RefreshUrl.clear();
 
-		// clear content
-		beginBuild();
-		resetCssStyle();
-
-		// start new rendering
-		_HtmlDOM = CHtmlElement(CHtmlElement::NONE, "<root>");
-
-		if (!trim(html).empty())
+		if (trim(html).empty())
 		{
+			// clear the page
+			beginBuild();
+				
+			// clear previous page and state
+			removeContent();
+
+			endBuild();
+		}
+		else
+		{
+			// browser.css
+			resetCssStyle();
+
+			// start new rendering
+			_HtmlDOM = CHtmlElement(CHtmlElement::NONE, "<root>");
+			_CurrentHTMLElement = NULL;
 			success = parseHtml(html);
 			if (success)
 			{
@@ -4214,10 +4146,6 @@ namespace NLGUI
 			}
 		}
 
-		endBuild();
-		updateRefreshButton();
-		_Browsing = false;
-
 		return success;
 	}
 
@@ -4250,8 +4178,24 @@ namespace NLGUI
 
 	// ***************************************************************************
 
+	void CGroupHTML::beginBuild ()
+	{
+		_Browsing = true;
+	}
+
 	void CGroupHTML::endBuild ()
 	{
+		// set the browser as complete
+		_Browsing = false;
+		updateRefreshButton();
+
+		// check that the title is set, or reset it (in the case the page
+		// does not provide a title)
+		if (_TitleString.empty())
+		{
+			setTitle(_TitlePrefix);
+		}
+
 		invalidateCoords();
 	}
 
@@ -4267,24 +4211,6 @@ namespace NLGUI
 	{
 	}
 
-	// ***************************************************************************
-	void CGroupHTML::requestTerminated()
-	{
-		if (_CurlWWW)
-		{
-	#if LOG_DL
-			nlwarning("(%s) stop curl, url '%s'", _Id.c_str(), _CurlWWW->Url.c_str());
-	#endif
-			if (MultiCurl)
-				curl_multi_remove_handle(MultiCurl, _CurlWWW->Request);
-
-			delete _CurlWWW;
-
-			_CurlWWW = NULL;
-			_Connecting = false;
-		}
-	}
-
 	// ***************************************************************************
 
 	string	CGroupHTML::home ()
@@ -4472,10 +4398,12 @@ namespace NLGUI
 	void	CGroupHTML::updateRefreshButton()
 	{
 		CCtrlBaseButton		*butRefresh = dynamic_cast<CCtrlBaseButton *>(CWidgetManager::getInstance()->getElementFromId(_BrowseRefreshButton));
-
-		bool enabled = !_Browsing && !_Connecting && !_URL.empty();
 		if(butRefresh)
-			butRefresh->setFrozen(!enabled);
+		{
+			// connecting, rendering, or is missing url
+			bool frozen = _CurlWWW || _Browsing || _URL.empty();
+			butRefresh->setFrozen(frozen);
+		}
 	}
 
 	// ***************************************************************************
@@ -4949,6 +4877,7 @@ namespace NLGUI
 	{
 		_WaitingForStylesheet = false;
 		_StylesheetQueue.clear();
+		_Style.reset();
 
 		std::string css;
 
@@ -4977,7 +4906,6 @@ namespace NLGUI
 		// table { border-spacing: 2px;} - overwrites cellspacing attribute
 		css += "table { border-collapse: separate;}";
 
-		_Style.reset();
 		_Style.parseStylesheet(css);
 	}
 	
@@ -5158,11 +5086,6 @@ namespace NLGUI
 				if (_TrustedDomain)
 					_Link.back() = suri;
 			}
-			else if (_TrustedDomain && suri[0] == '#' && _LuaHrefHack)
-			{
-				// Direct url (hack for lua beginElement)
-				_Link.back() = suri.substr(1);
-			}
 			else
 			{
 				// convert href from "?key=val" into "http://domain.com/?key=val"
diff --git a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
index a599cd18b..f749d9227 100644
--- a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
+++ b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp
@@ -3207,7 +3207,6 @@ void	CLuaIHMRyzom::browseNpcWebPage(const std::string &htmlId, const std::string
 		groupHtml->setTimeout((float)std::max(0.0, timeout));
 
 		// Browse the url
-		groupHtml->clean();
 		groupHtml->browse(url.c_str());
 		// Set top of the page
 		CCtrlScroll *pScroll = groupHtml->getScrollBar();

From 2c92ec7909dfb6c68f38a664fbb05451e20cd312 Mon Sep 17 00:00:00 2001
From: Inky <jnk@mailoo.org>
Date: Tue, 30 Apr 2019 16:59:15 +0300
Subject: [PATCH 23/75] Added: item sheets scroll properties

execute lua code, open webig and set menu label

--HG--
branch : develop
---
 code/ryzom/client/src/client_sheets/item_sheet.cpp | 11 ++++++++++-
 code/ryzom/client/src/client_sheets/item_sheet.h   |  6 ++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/code/ryzom/client/src/client_sheets/item_sheet.cpp b/code/ryzom/client/src/client_sheets/item_sheet.cpp
index e13d8e267..daac055fe 100644
--- a/code/ryzom/client/src/client_sheets/item_sheet.cpp
+++ b/code/ryzom/client/src/client_sheets/item_sheet.cpp
@@ -367,6 +367,11 @@ void CItemSheet::build(const NLGEORGES::UFormElm &item)
 	if (!val.empty())
 		CraftPlan = CSheetId(val);
 
+	// commands and menu label
+	TRANSLATE_VAL( Scroll.LuaCommand, "basics.Scroll.LuaCommand" );
+	TRANSLATE_VAL( Scroll.WebCommand, "basics.Scroll.WebCommand" );
+	TRANSLATE_VAL( Scroll.Label, "basics.Scroll.Label" );
+
 	// Special according to Family;
 	switch(Family)
 	{
@@ -658,6 +663,9 @@ void CItemSheet::serial(NLMISC::IStream &f)
 	// **** Serial Help Infos
 	f.serialEnum(ItemOrigin);
 
+	// item commands
+	f.serial(Scroll);
+
 	// Different Serial according to family
 	switch(Family)
 	{
@@ -697,8 +705,9 @@ void CItemSheet::serial(NLMISC::IStream &f)
 	case ITEMFAMILY::TELEPORT:
 		f.serial(Teleport);
 		break;
+	// keep for readability
 	case ITEMFAMILY::SCROLL:
-		f.serial(Scroll);
+		//f.serial(Scroll);
 		break;
 	case ITEMFAMILY::CONSUMABLE:
 		f.serial(Consumable);
diff --git a/code/ryzom/client/src/client_sheets/item_sheet.h b/code/ryzom/client/src/client_sheets/item_sheet.h
index c363c9756..bd79b1569 100644
--- a/code/ryzom/client/src/client_sheets/item_sheet.h
+++ b/code/ryzom/client/src/client_sheets/item_sheet.h
@@ -255,10 +255,16 @@ public:
 	struct CScroll
 	{
 		std::string Texture;
+		std::string LuaCommand;
+		std::string WebCommand;
+		std::string Label;
 
 		void	serial(NLMISC::IStream &f)
 		{
 			f.serial(Texture);
+			f.serial(LuaCommand);
+			f.serial(WebCommand);
+			f.serial(Label);
 		}
 	};
 

From 17945d24b03b7c0d135085888f39dacb5233a1bd Mon Sep 17 00:00:00 2001
From: Inky <jnk@mailoo.org>
Date: Tue, 30 Apr 2019 01:33:39 +0300
Subject: [PATCH 24/75] Added: CGroup menu set action handler

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_menu.h |  5 ++++
 code/nel/src/gui/group_menu.cpp       | 36 +++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/code/nel/include/nel/gui/group_menu.h b/code/nel/include/nel/gui/group_menu.h
index cfe91f7f9..ecdd8aff0 100644
--- a/code/nel/include/nel/gui/group_menu.h
+++ b/code/nel/include/nel/gui/group_menu.h
@@ -137,6 +137,9 @@ namespace NLGUI
 		const std::string getActionHandler(uint lineIndex) const;
 		const std::string getActionHandlerParam(uint lineIndex) const;
 
+		void setActionHandler(uint lineIndex, const std::string &ah = "");
+		void setActionHandlerParam(uint lineIndex, const std::string &params = "");
+
 		void	openSubMenu (sint32 nb);
 
 		void	hideSubMenus ();
@@ -330,6 +333,8 @@ namespace NLGUI
 		const std::string getActionHandler(uint lineIndex) const;
 		const std::string getActionHandlerParam(uint lineIndex) const;
 
+		void setActionHandler(uint lineIndex, const std::string &ah = "");
+		void setActionHandlerParam(uint lineIndex, const std::string &params = "");
 
 		void addLine (const ucstring &name, const std::string &ah = "", const std::string &params = "",
 					  const std::string &id = std::string(),
diff --git a/code/nel/src/gui/group_menu.cpp b/code/nel/src/gui/group_menu.cpp
index d8b3452ed..15a655d76 100644
--- a/code/nel/src/gui/group_menu.cpp
+++ b/code/nel/src/gui/group_menu.cpp
@@ -1663,6 +1663,28 @@ namespace NLGUI
 		return _Lines[lineIndex].AHParams;
 	}
 
+	// ------------------------------------------------------------------------------------------------
+	void CGroupSubMenu::setActionHandler(uint lineIndex, const std::string &ah)
+	{
+		if (lineIndex > _Lines.size())
+		{
+			nlwarning("Bad index");
+			return;
+		}
+		_Lines[lineIndex].AHName = ah;
+	}
+
+	// ------------------------------------------------------------------------------------------------
+	void CGroupSubMenu::setActionHandlerParam(uint lineIndex, const std::string &params)
+	{
+		if (lineIndex > _Lines.size())
+		{
+			nlwarning("Bad index");
+			return;
+		}
+		_Lines[lineIndex].AHParams = params;
+	}
+
 	// ------------------------------------------------------------------------------------------------
 	void CGroupSubMenu::setSelectable(uint lineIndex, bool selectable)
 	{
@@ -2596,6 +2618,20 @@ namespace NLGUI
 		return _RootMenu ? _RootMenu->getActionHandlerParam(lineIndex) : "";
 	}
 
+	// ------------------------------------------------------------------------------------------------
+	void CGroupMenu::setActionHandler(uint lineIndex, const std::string &ah)
+	{
+		if (_RootMenu)
+			_RootMenu->setActionHandler(lineIndex, ah);
+	}
+
+	// ------------------------------------------------------------------------------------------------
+	void CGroupMenu::setActionHandlerParam(uint lineIndex, const std::string &params)
+	{
+		if (_RootMenu)
+			_RootMenu->setActionHandlerParam(lineIndex, params);
+	}
+
 	// ------------------------------------------------------------------------------------------------
 	void CGroupMenu::setUserGroupRight(uint line, CInterfaceGroup *gr, bool ownerShip /*=true*/)
 	{

From 59da139eb740a25a7f7a24d0c2c1b6d28b73fe4b Mon Sep 17 00:00:00 2001
From: Inky <jnk@mailoo.org>
Date: Tue, 30 Apr 2019 02:52:54 +0300
Subject: [PATCH 25/75] Changed: introduce new proprieties menu and action
 handler

--HG--
branch : develop
---
 .../src/interface_v3/action_handler_item.cpp  | 109 +++++++++++++++++-
 1 file changed, 108 insertions(+), 1 deletion(-)

diff --git a/code/ryzom/client/src/interface_v3/action_handler_item.cpp b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
index d15ae130c..99c1147d3 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_item.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
@@ -430,7 +430,7 @@ static	TStackMode		CurrentStackMode;
 
 
 static void validateStackItem(CDBCtrlSheet *src, CDBCtrlSheet *dest, sint32 quantity, TStackMode stackMode);
-
+static void checkItemCommand(const CItemSheet *itemSheet);
 
 //=====================================================================================================================
 /** Send a swap item msg to the server
@@ -1672,6 +1672,10 @@ class CHandlerItemCristalReload : public IActionHandler
 		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
 		if (pCS == NULL) return;
 
+		const CItemSheet *pIS = pCS->asItemSheet();
+		if (pIS && pIS->Scroll.Label.empty())
+			checkItemCommand(pIS);
+
 		sendToServerEnchantMessage((uint8)pCS->getInventoryIndex(), (uint16)pCS->getIndexInDB());
 	}
 };
@@ -1749,6 +1753,7 @@ class CHandlerItemMenuCheck : public IActionHandler
 		CViewTextMenu	*pCrisReload = dynamic_cast<CViewTextMenu*>(pMenu->getView("cris_reload"));
 		CViewTextMenu	*pTeleportUse = dynamic_cast<CViewTextMenu*>(pMenu->getView("teleport_use"));
 		CViewTextMenu	*pItemConsume = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_consume"));
+		CViewTextMenu	*pItemExecute = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_execute"));
 		CViewTextMenu	*pXpCatalyserUse = dynamic_cast<CViewTextMenu*>(pMenu->getView("xp_catalyser_use"));
 		CViewTextMenu	*pDrop = dynamic_cast<CViewTextMenu*>(pMenu->getView("drop"));
 		CViewTextMenu	*pDestroy = dynamic_cast<CViewTextMenu*>(pMenu->getView("destroy"));
@@ -1776,6 +1781,7 @@ class CHandlerItemMenuCheck : public IActionHandler
 		if(pCrisReload)	pCrisReload->setActive(false);
 		if(pTeleportUse) pTeleportUse->setActive(false);
 		if(pItemConsume) pItemConsume->setActive(false);
+		if(pItemExecute) pItemExecute->setActive(false);
 		if(pXpCatalyserUse) pXpCatalyserUse->setActive(false);
 		if(pItemTextDisplay) pItemTextDisplay->setActive(false);
 		if(pItemTextEdition) pItemTextEdition->setActive(false);
@@ -1850,6 +1856,61 @@ class CHandlerItemMenuCheck : public IActionHandler
 			{
 				pItemInfos->setActive(true);
 			}
+			// item has a label?
+			if (!pIS->Scroll.Label.empty())
+			{
+				CGroupMenu *menu = dynamic_cast<CGroupMenu *>(
+					CWidgetManager::getInstance()->getElementFromId("ui:interface:item_menu_in_bag")
+				);
+				// add the label to default menu
+				if (!pIS->Scroll.LuaCommand.empty() || !pIS->Scroll.WebCommand.empty())
+					menu->setActionHandler(4, menu->getActionHandler(4));
+				else
+				{
+					// replace default menu and redirect action handler
+					if (pCrisEnchant && pCrisEnchant->getActive())
+					{
+						pCrisEnchant->setActive(false);
+						menu->setActionHandler(4, menu->getActionHandler(0));
+					}
+					if (pCrisReload && pCrisReload->getActive())
+					{
+						pCrisReload->setActive(false);
+						menu->setActionHandler(4, menu->getActionHandler(1));
+					}
+					if (pTeleportUse && pTeleportUse->getActive())
+					{
+						pTeleportUse->setActive(false);
+						menu->setActionHandler(4, menu->getActionHandler(2));
+					}
+					if (pItemConsume && pItemConsume->getActive())
+					{
+						pItemConsume->setActive(false);
+						menu->setActionHandler(4, menu->getActionHandler(3));
+					}
+					if (pXpCatalyserUse && pXpCatalyserUse->getActive())
+					{
+						pXpCatalyserUse->setActive(false);
+						menu->setActionHandler(4, menu->getActionHandler(5));
+					}
+					if (pItemTextDisplay && pItemTextDisplay->getActive())
+					{
+						pItemTextDisplay->setActive(false);
+						menu->setActionHandler(4, menu->getActionHandler(6));
+						menu->setActionHandlerParam(4, menu->getActionHandlerParam(6));
+					}
+				}
+				if (!bIsLockedByOwner)
+				{
+					if (pCS->getInventoryIndex() == INVENTORIES::bag)
+						pItemExecute->setActive(true);
+					// enchant and reload can be used from anywhere
+					if (pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL || pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE)
+						pItemExecute->setActive(true);
+
+					pItemExecute->setText(CI18N::get(pIS->Scroll.Label));
+				}
+			}
 		}
 
 		CInventoryManager	&invMngr= getInventory();
@@ -1980,6 +2041,7 @@ class CHandlerItemMenuCheck : public IActionHandler
 			if(pCrisReload)		pCrisReload->setGrayed(true);
 			if(pTeleportUse)	pTeleportUse->setGrayed(true);
 			if(pItemConsume)	pItemConsume->setGrayed(true);
+			if(pItemExecute)	pItemExecute->setGrayed(true);
 			if(pXpCatalyserUse)	pXpCatalyserUse->setGrayed(true);
 			if(pDrop)			pDrop->setGrayed(true);
 			if(pDestroy)		pDestroy->setGrayed(true);
@@ -1999,6 +2061,7 @@ class CHandlerItemMenuCheck : public IActionHandler
 			if(pCrisReload)		pCrisReload->setGrayed(false);
 			if(pTeleportUse)	pTeleportUse->setGrayed(false);
 			if(pItemConsume)	pItemConsume->setGrayed(false);
+			if(pItemExecute)	pItemExecute->setGrayed(false);
 			if(pXpCatalyserUse)	pXpCatalyserUse->setGrayed(false);
 			if(pDrop)			pDrop->setGrayed(false);
 			if(pDestroy)		pDestroy->setGrayed(false);
@@ -2179,6 +2242,24 @@ static void sendMsgStopUseXpCat( bool isRingCatalyser )
 	}
 }
 
+// ***************************************************************************
+static void checkItemCommand(const CItemSheet *itemSheet)
+{
+	if (itemSheet)
+	{
+		if (!itemSheet->Scroll.LuaCommand.empty())
+			CLuaManager::getInstance().executeLuaScript(itemSheet->Scroll.LuaCommand);
+		// webig
+		if (!itemSheet->Scroll.WebCommand.empty())
+		{
+			CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(
+				CWidgetManager::getInstance()->getElementFromId("ui:interface:web_transactions:content:html")
+			);
+			if (pGH) pGH->browse(itemSheet->Scroll.WebCommand.c_str());
+		}
+	}
+	return;
+}
 
 // ***************************************************************************
 class CHandlerTeleportUse : public IActionHandler
@@ -2207,6 +2288,8 @@ class CHandlerTeleportUse : public IActionHandler
 					LoadingBackground = TeleportKaravanBackground;
 				break;
 			}
+			if (pIS->Scroll.Label.empty())
+				checkItemCommand(pIS);
 		}
 	}
 };
@@ -2221,12 +2304,28 @@ class CHandlerItemConsume : public IActionHandler
 		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
 		if (pCS == NULL) return;
 
+		const CItemSheet *pIS = pCS->asItemSheet();
+		if (pIS && pIS->Scroll.Label.empty())
+			checkItemCommand(pIS);
+
 		// use the item
 		sendMsgUseItem(uint16(pCS->getIndexInDB()));
 	}
 };
 REGISTER_ACTION_HANDLER( CHandlerItemConsume, "item_consume" );
 
+// ***************************************************************************
+class CHandlerItemExecute : public IActionHandler
+{
+	void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
+	{
+		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
+		if (pCS)
+			checkItemCommand(pCS->asItemSheet());
+		return;
+	}
+};
+REGISTER_ACTION_HANDLER( CHandlerItemExecute, "item_execute" );
 
 // ***************************************************************************
 class CHandlerValidateItemTextEdition : public IActionHandler
@@ -2250,6 +2349,10 @@ class CHandlerItemTextDisplay : public IActionHandler
 		if (pCSItem == NULL || windowName.empty()) 
 			return;
 
+		const CItemSheet *pIS = pCSItem->asItemSheet();
+		if (pIS && pIS->Scroll.Label.empty())
+			checkItemCommand(pIS);
+
 		CInterfaceItemEdition::getInstance()->setCurrWindow(pCSItem, windowName, false);
 	}
 };
@@ -2291,6 +2394,10 @@ class CHandlerXpCatalyserUse : public IActionHandler
 		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
 		if (pCS == NULL) return;
 
+		const CItemSheet *pIS = pCS->asItemSheet();
+		if (pIS && pIS->Scroll.Label.empty())
+			checkItemCommand(pIS);
+
 		// use the item
 		sendMsgUseItem(uint16(pCS->getIndexInDB()));
 	}

From d2fc5d200e3bc476207bd04f990376fab5dc9e30 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Tue, 30 Apr 2019 12:25:11 +0800
Subject: [PATCH 26/75] Fix build...

---
 code/nel/include/nel/misc/common.h            |  2 +
 code/nel/include/nel/misc/types_nl.h          |  1 +
 .../misc/branch_patcher/branch_patcherDlg.cpp | 48 +++++++++++--------
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index 150780877..8ad0b5dcc 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -312,12 +312,14 @@ inline sint nlstricmp(const char *lhs, const std::string &rhs) { return stricmp(
 #ifdef _UNICODE
 #define tStrToUtf8(str) (ucstring((ucchar*)(LPCWSTR)str).toUtf8())
 #define utf8ToTStr(str) ((const wchar_t *)ucstring::makeFromUtf8(str).c_str())
+#define tstring wstring
 #else
 // FIXME: This is not accurate, it should be a conversion between local charset and utf8
 #define tStrToUtf8(str) (std::string((LPCSTR)str))
 inline const char *nlutf8ToTStr(const char *str) { return str; }
 inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
 #define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
+#define tstring string
 #endif
 
 #if (NL_COMP_VC_VERSION <= 90)
diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h
index 6431701fe..1a1da7be2 100644
--- a/code/nel/include/nel/misc/types_nl.h
+++ b/code/nel/include/nel/misc/types_nl.h
@@ -220,6 +220,7 @@
 #	if defined(NL_COMP_VC8) || defined(NL_COMP_VC9) || defined(NL_COMP_VC10)
 #		pragma warning (disable : 4005)			// don't warn on redefinitions caused by xp platform sdk
 #	endif // NL_COMP_VC8 || NL_COMP_VC9
+#	pragma warning (disable : 26495)		// Variable is uninitialized. Always initialize a member variable. (On purpose for performance.)
 #endif // NL_OS_WINDOWS
 
 
diff --git a/code/nel/tools/misc/branch_patcher/branch_patcherDlg.cpp b/code/nel/tools/misc/branch_patcher/branch_patcherDlg.cpp
index 134eddebf..d185e16b6 100644
--- a/code/nel/tools/misc/branch_patcher/branch_patcherDlg.cpp
+++ b/code/nel/tools/misc/branch_patcher/branch_patcherDlg.cpp
@@ -208,13 +208,13 @@ int CDirDialog::DoBrowse()
 	}
 
 	BROWSEINFO bInfo;
+	LPITEMIDLIST pidl;
 	ZeroMemory((PVOID)&bInfo, sizeof(BROWSEINFO));
 
 	if (!m_strInitDir.IsEmpty())
 	{
 		OLECHAR       olePath[MAX_PATH];
-		ULONG         chEaten;
-		ULONG         dwAttributes;
+		ULONG         dwAttributes = 0;
 		HRESULT       hr;
 		LPSHELLFOLDER pDesktopFolder;
 		// // Get a pointer to the Desktop's IShellFolder interface. //
@@ -236,7 +236,7 @@ int CDirDialog::DoBrowse()
 			hr = pDesktopFolder->ParseDisplayName(NULL,
 				NULL,
 				olePath,
-				&chEaten,
+				NULL,
 				&pidl,
 				&dwAttributes);
 
@@ -248,7 +248,6 @@ int CDirDialog::DoBrowse()
 			}
 
 			bInfo.pidlRoot = pidl;
-
 		}
 	}
 
@@ -257,8 +256,10 @@ int CDirDialog::DoBrowse()
 	bInfo.lpszTitle = (m_strTitle.IsEmpty()) ? "Open" : m_strTitle;
 	bInfo.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
 
-	PIDLIST_ABSOLUTE pidl = ::SHBrowseForFolder(&bInfo);
-	if (!pidl) return 0;
+	if ((pidl = ::SHBrowseForFolder(&bInfo)) == NULL)
+	{
+		return 0;
+	}
 
 	m_strPath.ReleaseBuffer();
 	m_iImageIndex = bInfo.iImage;
@@ -288,19 +289,26 @@ BOOL SendTextToClipboard(CString source)
 	if (OpenClipboard(NULL))
 	{
 		HGLOBAL clipbuffer;
-		char* buffer;
+		TCHAR* buffer;
 
 		EmptyClipboard(); // Empty whatever's already there
 
-		clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength() + 1);
-		buffer = (char*)GlobalLock(clipbuffer);
-		strcpy(buffer, LPCSTR(source));
-		GlobalUnlock(clipbuffer);
+		clipbuffer = GlobalAlloc(GMEM_DDESHARE, ((SIZE_T)source.GetLength() + 1) * sizeof(TCHAR));
+		if (clipbuffer)
+		{
+			buffer = (TCHAR*)GlobalLock(clipbuffer);
+			if (buffer)
+			{
+				_tcscpy(buffer, LPCTSTR(source));
+				GlobalUnlock(clipbuffer);
 
-		SetClipboardData(CF_TEXT, clipbuffer); // Send the data
+				SetClipboardData(CF_TEXT, clipbuffer); // Send the data
 
+				CloseClipboard(); // VERY IMPORTANT
+				return TRUE;
+			}
+		}
 		CloseClipboard(); // VERY IMPORTANT
-		return TRUE;
 	}
 	return FALSE;
 }
@@ -326,11 +334,11 @@ void CBranch_patcherDlg::OnButtonPatch()
 	CString text;
 	text.Format(_T("Get diff from directory %s?\n\nCommand (choose No to copy it into the clipboard):\n%s"), m_SrcDir, diffCmdLine);
 	int result;
-	if ((result = ::MessageBox(m_hWnd, text, "Confirmation", MB_YESNOCANCEL | MB_ICONQUESTION)) == IDYES)
+	if ((result = ::MessageBox(m_hWnd, text, _T("Confirmation"), MB_YESNOCANCEL | MB_ICONQUESTION)) == IDYES)
 	{
-		if (_chdir(m_SrcDir) == 0)
+		if (_tchdir(m_SrcDir) == 0)
 		{
-			system(diffCmdLine);
+			_tsystem(diffCmdLine);
 			displayFile(TEMP_DIFF_FILE);
 			SaveDiff = true;
 			colorizeDiff();
@@ -461,11 +469,11 @@ void CBranch_patcherDlg::OnDoPatch()
 	int result;
 	if ((result = ::MessageBox(m_hWnd, text, _T("Confirmation"), MB_YESNOCANCEL | MB_ICONQUESTION)) == IDYES)
 	{
-		if (_chdir(m_DestDir) == 0)
+		if (_tchdir(m_DestDir) == 0)
 		{
-			system(patchCmdLine);
-			system(concatOutput);
-			system(delPatchErrors);
+			_tsystem(patchCmdLine);
+			_tsystem(concatOutput);
+			_tsystem(delPatchErrors);
 			displayFile(PATCH_RESULT);
 			SaveDiff = false;
 			m_Display->LineScroll(0);

From bb792b830718a0e60d9b4224809f59776ac815a1 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Tue, 30 Apr 2019 12:53:26 +0800
Subject: [PATCH 27/75] Fixing unicode in georges edit dll

---
 .../tools/leveldesign/georges_dll/action.cpp  | 20 +++---
 .../tools/leveldesign/georges_dll/action.h    | 11 +--
 .../leveldesign/georges_dll/base_dialog.cpp   |  2 +-
 .../leveldesign/georges_dll/base_dialog.h     |  2 +-
 .../leveldesign/georges_dll/dfn_dialog.cpp    | 20 +++---
 .../leveldesign/georges_dll/form_dialog.cpp   | 72 +++++++++----------
 .../leveldesign/georges_dll/georges_edit.cpp  |  4 +-
 .../leveldesign/georges_dll/georges_edit.h    | 18 ++---
 .../georges_dll/memory_combo_box.cpp          |  4 +-
 .../georges_dll/memory_combo_box.h            |  4 +-
 10 files changed, 79 insertions(+), 78 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/georges_dll/action.cpp b/code/ryzom/tools/leveldesign/georges_dll/action.cpp
index 6e173756e..c2e9562fd 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/action.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/action.cpp
@@ -44,7 +44,7 @@ IAction::IAction (TTypeAction type, uint selId, uint slot)
 
 // ***************************************************************************
 
-void IAction::setLabel (const std::string &logLabel, CGeorgesEditDoc &doc)
+void IAction::setLabel (const char *logLabel, CGeorgesEditDoc &doc)
 {
 	_LogLabel = logLabel;
 
@@ -75,7 +75,7 @@ bool IAction::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, bool fi
 
 // ***************************************************************************
 
-void IAction::update (bool updateLeftView, TUpdateRightView rightViewFlag, CGeorgesEditDoc &doc, const std::string &_FormName)
+void IAction::update (bool updateLeftView, TUpdateRightView rightViewFlag, CGeorgesEditDoc &doc, const char *_FormName)
 {
 	// Right and left view
 	CGeorgesEditView *rightView = doc.getRightView ();
@@ -129,7 +129,7 @@ void IAction::update (bool updateLeftView, TUpdateRightView rightViewFlag, CGeor
 
 // ***************************************************************************
 
-CActionString::CActionString (IAction::TTypeAction type, const std::string &newValue, CGeorgesEditDoc &doc, const std::string &formName, const std::string &userData, uint selId, uint slot) : IAction (type, selId, slot)
+CActionString::CActionString (IAction::TTypeAction type, const char *newValue, CGeorgesEditDoc &doc, const char *formName, const char *userData, uint selId, uint slot) : IAction (type, selId, slot)
 {
 	// Set the new value
 	_NewValue = newValue;
@@ -235,7 +235,7 @@ CActionString::CActionString (IAction::TTypeAction type, const std::string &newV
 			bool vdfnArray;
 			CForm *form=doc.getFormPtr ();
 			CFormElm *elm = doc.getRootNode (slot);
-			nlverify ( elm->getNodeByName (_FormName, &parentDfn, indexDfn, 
+			nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn, 
 				&nodeDfn, &nodeType, &node, type, array, vdfnArray, true, NLGEORGES_FIRST_ROUND) );
 			if (node)
 			{
@@ -364,7 +364,7 @@ bool CActionString::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, b
 					bool parentVDnfArray;
 					CForm *form=doc.getFormPtr ();
 					CFormElm *elm = doc.getRootNode (_Slot);
-					nlverify ( elm->getNodeByName (_FormName, &parentDfn, indexDfn, 
+					nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn, 
 						&nodeDfn, &nodeType, &node, type, array, parentVDnfArray, true, NLGEORGES_FIRST_ROUND) );
 					nlassert (node);
 					CFormElmAtom *atom = safe_cast<CFormElmAtom*> (node);
@@ -437,14 +437,14 @@ bool CActionString::doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, b
 			bool vdfnArray;
 			CForm *form=doc.getFormPtr ();
 			CFormElm *elm = doc.getRootNode (_Slot);
-			nlverify ( elm->getNodeByName (_FormName, &parentDfn, indexDfn, 
+			nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn, 
 				&nodeDfn, &nodeType, &node, type, array, vdfnArray, true, NLGEORGES_FIRST_ROUND) );
 			if (node)
 			{
 				CFormElmArray* array = safe_cast<CFormElmArray*> (node->getParent ());
 				array->Elements[idInParent].Name = _Value[index];
 				modified = true;
-				update (true, DoNothing, doc, _FormName);
+				update (true, DoNothing, doc, _FormName.c_str ());
 			}
 		}
 		break;
@@ -716,14 +716,14 @@ bool CActionStringVector::doAction (CGeorgesEditDoc &doc, bool redo, bool &modif
 			bool parentVDfnArray;
 			CForm *form=doc.getFormPtr ();
 			CFormElm *elm = doc.getRootNode (slot);
-			nlverify ( elm->getNodeByName (_FormName, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true) );
+			nlverify ( elm->getNodeByName (_FormName.c_str (), &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true) );
 
 			// Is a type entry ?
 			if ((type == UFormDfn::EntryType) && array)
 			{
 				// Create the array
 				bool created;
-				nlverify ( elm->createNodeByName (_FormName, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, created) );
+				nlverify ( elm->createNodeByName (_FormName.c_str (), &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, created) );
 				nlassert (node);
 
 				// Get the atom
@@ -921,7 +921,7 @@ bool CActionStringVectorVector::doAction (CGeorgesEditDoc &doc, bool redo, bool
 
 // ***************************************************************************
 
-CActionBuffer::CActionBuffer(IAction::TTypeAction type, const uint8 *buffer, uint bufferSize, CGeorgesEditDoc &doc, const std::string &formName, const std::string &userData, uint selId, uint slot) : IAction(type, selId, slot)
+CActionBuffer::CActionBuffer (IAction::TTypeAction type, const uint8 *buffer, uint bufferSize, CGeorgesEditDoc &doc, const char *formName, const char *userData, uint selId, uint slot) : IAction (type, selId, slot)
 {
 	// New value
 	_FormName = formName;
diff --git a/code/ryzom/tools/leveldesign/georges_dll/action.h b/code/ryzom/tools/leveldesign/georges_dll/action.h
index 95af8015e..caf49373a 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/action.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/action.h
@@ -59,7 +59,7 @@ protected:
 	IAction (TTypeAction type, uint selId, uint slot);
 
 	// Init log label
-	void setLabel (const std::string &logLabel, CGeorgesEditDoc &doc);
+	void setLabel (const char *logLabel, CGeorgesEditDoc &doc);
 
 public:
 
@@ -96,7 +96,7 @@ protected:
 		UpdateValues,
 		Redraw
 	};
-	void			update (bool updateLeftView, TUpdateRightView rightView, CGeorgesEditDoc &doc, const std::string &_FormName);
+	void			update (bool updateLeftView, TUpdateRightView rightView, CGeorgesEditDoc &doc, const char *_FormName);
 };
 
 // String modification action
@@ -105,7 +105,7 @@ class CActionString : public IAction
 public:
 
 	// Constructor
-	CActionString(IAction::TTypeAction type, const std::string &newValue, CGeorgesEditDoc &doc, const std::string &formName, const std::string &userData, uint selId, uint slot);
+	CActionString (IAction::TTypeAction type, const char *newValue, CGeorgesEditDoc &doc, const char *formName, const char *userData, uint selId, uint slot);
 
 protected:
 
@@ -165,7 +165,7 @@ class CActionBuffer : public IAction
 public:
 
 	// Constructor
-	CActionBuffer (IAction::TTypeAction type, const uint8 *buffer, uint bufferSize, CGeorgesEditDoc &doc, const std::string &formName, const std::string &userData, uint selId, uint slot);
+	CActionBuffer (IAction::TTypeAction type, const uint8 *buffer, uint bufferSize, CGeorgesEditDoc &doc, const char *formName, const char *userData, uint selId, uint slot);
 
 protected:
 
@@ -182,4 +182,5 @@ protected:
 	virtual bool	doAction (CGeorgesEditDoc &doc, bool redo, bool &modified, bool firstTime);
 };
 
-#endif
+#endif /* GEORGES_EDIT_ACTION_H */
+
diff --git a/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp
index a29c9f7d7..ffacde032 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp
@@ -230,7 +230,7 @@ BOOL CBaseDialog::PreTranslateMessage(MSG* pMsg)
 	return CDialog::PreTranslateMessage(pMsg);
 }
 
-void CBaseDialog::setEditTextMultiLine (CEdit &edit, const std::string &text)
+void CBaseDialog::setEditTextMultiLine (CEdit &edit, const char *text)
 {
 	edit.SetWindowText (utf8ToTStr(NLMISC::addSlashR(text)));
 }	
diff --git a/code/ryzom/tools/leveldesign/georges_dll/base_dialog.h b/code/ryzom/tools/leveldesign/georges_dll/base_dialog.h
index 6358697b7..5f96d8229 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/base_dialog.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/base_dialog.h
@@ -126,7 +126,7 @@ public:
 	void	registerLastControl ();
 	void	unRegisterLastControl ();
 
-	static void setEditTextMultiLine(CEdit &edit, const std::string &text);
+	static void setEditTextMultiLine (CEdit &edit, const char *text);
 
 	virtual void onOpenSelected ();
 	virtual void setFocusLastWidget ();
diff --git a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
index 22c556faa..1ddbe46b1 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
@@ -468,16 +468,16 @@ void CDfnDialog::onOpenSelected ()
 					int nItem = Parents.ListCtrl.GetNextSelectedItem(pos);
 
 					// Get the string
-					std::string str = tStrToUtf8(Parents.ListCtrl.GetItemText (nItem, 0));
-					if (!str.empty())
+					CString str = Parents.ListCtrl.GetItemText (nItem, 0);
+					if (str != "")
 					{
 						// Look for the file
-						string name = CPath::lookup (str, false, false);
-						if (name.empty ())
+						CString name = utf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
+						if (name.IsEmpty())
 							name = str;
 
 						// Open the file
-						theApp.OpenDocumentFile (utf8ToTStr(name));
+						theApp.OpenDocumentFile(name);
 					}
 				}
 			}
@@ -490,16 +490,16 @@ void CDfnDialog::onOpenSelected ()
 					int nItem = Struct.ListCtrl.GetNextSelectedItem(pos);
 
 					// Get the string
-					std::string str = tStrToUtf8(Struct.ListCtrl.GetItemText (nItem, 2));
-					if (!str.empty())
+					CString str = Struct.ListCtrl.GetItemText (nItem, 2);
+					if (str != "")
 					{
 						// Look for the file
-						string name = CPath::lookup (str, false, false);
-						if (name.empty ())
+						CString name = utf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
+						if (name.IsEmpty())
 							name = str;
 
 						// Open the file
-						theApp.OpenDocumentFile (utf8ToTStr(name));
+						theApp.OpenDocumentFile(name);
 					}
 				}
 			}
diff --git a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
index f4fcf4d1d..8cf257035 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
@@ -548,7 +548,7 @@ void CFormDialog::setToDocument (uint widget)
 			bool parentVDfnArray;
 			CForm *form=doc->getFormPtr ();
 			CFormElm *elm = doc->getRootNode (Widgets[widget]->getSlot ());
-			nlverify ( elm->getNodeByName (Widgets[widget]->getFormName (), &parentDfn, indexDfn, 
+			nlverify ( elm->getNodeByName (Widgets[widget]->getFormName ().c_str (), &parentDfn, indexDfn, 
 				&nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND) );
 
 			// Must create array or virtual dfn ?
@@ -811,7 +811,7 @@ BOOL CFormDialog::OnCommand(WPARAM wParam, LPARAM lParam)
 							bool parentVDfnArray;
 							CForm *form=doc->getFormPtr ();
 							CFormElm *elm = doc->getRootNode (Widgets[widgetId]->getSlot ());
-							nlverify ( elm->getNodeByName (Widgets[widgetId]->getFormName (), &parentDfn, indexDfn, 
+							nlverify ( elm->getNodeByName (Widgets[widgetId]->getFormName ().c_str (), &parentDfn, indexDfn, 
 								&nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND) );
 							nlassert (parentDfn);
 
@@ -832,11 +832,11 @@ BOOL CFormDialog::OnCommand(WPARAM wParam, LPARAM lParam)
 							smprintf (filter, 512, "%s Files (%s)|%s|All Files(*.*)|*.*|", typeName+i, ext.c_str(), ext.c_str());
 
 							// Open the dialog
-							CFileDialog dlgFile (TRUE, ext.c_str (), ext.c_str (), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, theApp.m_pMainWnd);
+							CFileDialog dlgFile(TRUE, utf8ToTStr(ext), utf8ToTStr(ext), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, utf8ToTStr(filter), theApp.m_pMainWnd);
 							if (dlgFile.DoModal () == IDOK)
 							{
 								combo->Combo.UpdateData ();
-								combo->Combo.SetWindowText (dlgFile.GetFileName ());
+								combo->Combo.SetWindowText(dlgFile.GetFileName());
 								combo->Combo.UpdateData (FALSE);
 								setToDocument (widgetId);
 								PostMessage (CBN_CHANGED, 0, 0);
@@ -850,7 +850,7 @@ BOOL CFormDialog::OnCommand(WPARAM wParam, LPARAM lParam)
 						if (colorEdit && IsWindow (colorEdit->Color))
 						{
 							colorEdit->Empty = true;
-							colorEdit->Edit.SetWindowText("");
+							colorEdit->Edit.SetWindowText(_T(""));
 							setToDocument (getWidget (wParam));
 							updateValues ();
 						}
@@ -926,7 +926,7 @@ BOOL CFormDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
 					CString str;
 					combo->Combo.UpdateData ();
 					combo->Combo.GetWindowText (str);
-					if (sscanf (str, "%f", &value) == 1)
+					if (_stscanf (str, _T("%f"), &value) == 1)
 					{
 						CGeorgesEditDoc *doc = View->GetDocument();
 						if (doc)
@@ -1166,14 +1166,14 @@ void CFormDialog::getFromDocument ()
 
 // ***************************************************************************
 
-void CFormDialog::getDfnName (string &result) const
+void CFormDialog::getDfnName(string &result) const
 {
 	CGeorgesEditDoc *doc = View->GetDocument ();
 	if (doc)
 	{
 		// Get the DFN filename
-		CString str = doc->GetPathName ();
-		result NLMISC::CFile::getExtension(tStrToUtf8(str));
+		CString str = doc->GetPathName();
+		result = NLMISC::CFile::getExtension(tStrToUtf8(str));
 	}
 	else
 		result.clear();
@@ -1316,16 +1316,16 @@ void IFormWidget::updateLabel ()
 					switch (where)
 					{
 					case UFormElm::ValueForm:
-						Label.SetWindowText ((SavedLabel+comp).c_str());
+						Label.SetWindowText(utf8ToTStr(SavedLabel + comp));
 						break;
 					case UFormElm::ValueParentForm:
-						Label.SetWindowText ((SavedLabel+" (in parent form)"+comp).c_str());
+						Label.SetWindowText(utf8ToTStr(SavedLabel + " (in parent form)" + comp));
 						break;
 					case UFormElm::ValueDefaultDfn:
-						Label.SetWindowText ((SavedLabel+" (default DFN value)"+comp).c_str());
+						Label.SetWindowText(utf8ToTStr(SavedLabel + " (default DFN value)" + comp));
 						break;
 					case UFormElm::ValueDefaultType:
-						Label.SetWindowText ((SavedLabel+" (default TYPE value)"+comp).c_str());
+						Label.SetWindowText(utf8ToTStr(SavedLabel + " (default TYPE value)" + comp));
 						break;
 					}
 				}
@@ -1569,7 +1569,7 @@ void CFormMemCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent,
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (label, WS_VISIBLE, currentPos, parent);
+	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -1603,7 +1603,7 @@ void CFormMemCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent,
 		RECT spinPos = currentPos;
 		parent->getNextBrowsePos (spinPos);
 		parent->setBrowseSize (spinPos);
-		Browse.Create ("...", WS_CHILD|WS_VISIBLE|WS_TABSTOP, spinPos, parent, dialog_index+1);
+		Browse.Create (_T("..."), WS_CHILD|WS_VISIBLE|WS_TABSTOP, spinPos, parent, dialog_index+1);
 		parent->initWidget (Browse);
 		parent->getNextPos (currentPos);
 
@@ -1675,7 +1675,7 @@ void CFormMemCombo::getValue (std::string &result)
 	Combo.UpdateData (FALSE);
 	
 	// Set the atom value
-	result = (const char*)str;
+	result = tStrToUtf8(str);
 }
 
 // ***************************************************************************
@@ -1720,7 +1720,7 @@ void CFormMemCombo::getFromDocument (CForm &form)
 			CFormElmArray *arrayNode = safe_cast<CFormElmArray*> (node);
 			char label[512];
 			smprintf (label, 512, "%d", arrayNode->Elements.size ());
-			Combo.SetWindowText (label);
+			Combo.SetWindowText (utf8ToTStr(label));
 
 			if (arrayNode->getForm () == &form)
 				Label.SetWindowText (_T("Array size:"));
@@ -1903,7 +1903,7 @@ void CFormCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, ui
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (label, WS_VISIBLE, currentPos, parent);
+	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -1918,10 +1918,10 @@ void CFormCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, ui
 	// Get predefs
 	if (nodeType)
 	{
-		Combo.InsertString (0, "");
+		Combo.InsertString (0, _T(""));
 		for (uint predef=0; predef<nodeType->Definitions.size(); predef++)
 		{
-			Combo.InsertString (predef+1, nodeType->Definitions[predef].Label.c_str());
+			Combo.InsertString (predef+1, utf8ToTStr(nodeType->Definitions[predef].Label));
 		}
 	}
 
@@ -1973,7 +1973,7 @@ void CFormCombo::getValue (std::string &result)
 	Combo.UpdateData (FALSE);
 
 	// Set the atom value
-	result = (const char*)str;
+	result = tStrToUtf8(str);
 }
 
 // ***************************************************************************
@@ -2088,13 +2088,13 @@ void CFormBigEdit::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent,
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (label, WS_VISIBLE, currentPos, parent);
+	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
 	// Create the mem combobox
 	parent->setBigEditSize (currentPos, parent->SmallWidget);
-	Edit.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), "", WS_VSCROLL|ES_OEMCONVERT|ES_MULTILINE|ES_WANTRETURN|WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL|ES_AUTOVSCROLL, currentPos, parent, dialog_index);
+	Edit.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), WS_VSCROLL|ES_OEMCONVERT|ES_MULTILINE|ES_WANTRETURN|WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL|ES_AUTOVSCROLL, currentPos, parent, dialog_index);
 	parent->initWidget (Edit);
 	parent->getNextPos (currentPos);
 
@@ -2146,7 +2146,7 @@ void CFormBigEdit::getValue (std::string &result)
 	Edit.UpdateData (FALSE);
 	
 	// Set the atom value
-	result = (const char*)str;
+	result = tStrToUtf8(str);
 }
 
 // ***************************************************************************
@@ -2262,7 +2262,7 @@ void CColorEdit::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, ui
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (label, WS_VISIBLE, currentPos, parent);
+	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -2275,13 +2275,13 @@ void CColorEdit::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, ui
 	RECT resetPos = currentPos;
 	parent->getNextColorPos (resetPos);
 	parent->setResetColorSize (resetPos);
-	Reset.Create ("Reset", WS_CHILD|WS_VISIBLE|WS_TABSTOP, resetPos, parent, dialog_index+1);
+	Reset.Create (_T("Reset"), WS_CHILD|WS_VISIBLE|WS_TABSTOP, resetPos, parent, dialog_index+1);
 	parent->initWidget (Reset);
 	parent->getNextPosLabel (currentPos);
 
 	// Create the Edit
 	parent->setBigEditSize (currentPos, parent->SmallWidget);
-	Edit.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), "", ES_OEMCONVERT|ES_WANTRETURN|WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL, currentPos, parent, dialog_index+2);
+	Edit.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), ES_OEMCONVERT|ES_WANTRETURN|WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL, currentPos, parent, dialog_index+2);
 	parent->initWidget (Edit);
 	parent->getNextPos (currentPos);
 
@@ -2492,7 +2492,7 @@ void CListWidget::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, u
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (label, WS_VISIBLE, currentPos, parent);
+	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -2504,7 +2504,7 @@ void CListWidget::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, u
 
 	// Create the assign parent
 	parent->setButtonSize (currentPos, parent->SmallWidget);
-	Button.Create ("Assign parents", WS_CHILD|WS_VISIBLE|WS_TABSTOP, currentPos, parent, dialog_index+1);
+	Button.Create (_T("Assign parents"), WS_CHILD|WS_VISIBLE|WS_TABSTOP, currentPos, parent, dialog_index+1);
 	parent->initWidget (Button);
 	parent->getNextPos (currentPos);
 
@@ -2515,7 +2515,7 @@ void CListWidget::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, u
 
 void CListWidget::addColumn (const char *name)
 {
-	ListCtrl.insertColumn (0, name);
+	ListCtrl.insertColumn (0, utf8ToTStr(name));
 	ListCtrl.recalcColumn ();
 }
 
@@ -2566,7 +2566,7 @@ void CListWidget::getFromDocument (NLGEORGES::CForm &form)
 		string filename = form.getParentFilename (parent);
 
 		// Insert in the list
-		ListCtrl.ListCtrl.InsertItem (parent, filename.c_str ());
+		ListCtrl.ListCtrl.InsertItem (parent, utf8ToTStr(filename));
 
 		ListCtrl.ListCtrl.UpdateData (FALSE);
 		updateLabel ();
@@ -2585,7 +2585,7 @@ uint CListWidget::getNumValue ()
 void CListWidget::getValue (std::string &result, uint value)
 {
 	CString str = ListCtrl.ListCtrl.GetItemText (value, 0);
-	result = str;
+	result = tStrToUtf8(str);
 }
 
 // ***************************************************************************
@@ -2709,12 +2709,12 @@ void CListWidget::onOpenSelected ()
 		if (str != "")
 		{
 			// Look for the file
-			string name = CPath::lookup ((const char*)str, false, false);
-			if (name.empty ())
+			CString name = utf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
+			if (name.IsEmpty())
 				name = str;
 
 			// Open the file
-			theApp.OpenDocumentFile (name.c_str ());
+			theApp.OpenDocumentFile(name);
 		}
 	}
 }
@@ -2750,7 +2750,7 @@ void CIconWidget::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, u
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (label, WS_VISIBLE, currentPos, parent);
+	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
index 5b1b5f72f..effc20681 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
@@ -1025,7 +1025,7 @@ void CGeorgesEditApp::OnUpdateFileSaveAll(CCmdUI* pCmdUI)
 	pCmdUI->Enable (getActiveDocument () != NULL);
 }
 
-bool CGeorgesEditApp::SerialIntoMemStream (const std::string &formName, CGeorgesEditDoc *doc, uint slot, bool copyToClipboard)
+bool CGeorgesEditApp::SerialIntoMemStream (const char *formName, CGeorgesEditDoc *doc, uint slot, bool copyToClipboard)
 {
 	// Ok, get the node
 	const CFormDfn *parentDfn;
@@ -1228,7 +1228,7 @@ bool CGeorgesEditApp::FillMemStreamWithClipboard (const char *formName, CGeorges
 		return false;
 }
 
-bool CGeorgesEditApp::SerialFromMemStream (const std::string &formName, CGeorgesEditDoc *doc, uint slot)
+bool CGeorgesEditApp::SerialFromMemStream (const char *formName, CGeorgesEditDoc *doc, uint slot)
 {
 	// The form pointer
 	CForm *form = doc->getFormPtr ();
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h
index 747e4aec7..6b233f590 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h
@@ -119,11 +119,11 @@ public:
 public:
 	// Memory stream
 	NLMISC::CMemStream	MemStream;
-	bool				FillMemStreamWithClipboard (const std::string &formName, CGeorgesEditDoc *doc, uint slot);
+	bool				FillMemStreamWithClipboard (const char *formName, CGeorgesEditDoc *doc, uint slot);
 	void				FillMemStreamWithBuffer (const uint8 *buffer, uint size);
 
-	bool				SerialIntoMemStream (const std::string &formName, CGeorgesEditDoc *doc, uint slot, bool copyToClipboard);
-	bool				SerialFromMemStream (const std::string &formName, CGeorgesEditDoc *doc, uint slot);
+	bool				SerialIntoMemStream (const char *formName, CGeorgesEditDoc *doc, uint slot, bool copyToClipboard);
+	bool				SerialFromMemStream (const char *formName, CGeorgesEditDoc *doc, uint slot);
 
 	// Init
 	BOOL initInstance (int nCmdShow, bool exeStandalone, int x, int y, int cx, int cy);
@@ -136,7 +136,7 @@ public:
 
 	// From IEdit
 	NLGEORGES::IEditDocument *getActiveDocument ();
-	NLGEORGES::IEditDocument *createDocument (const std::string &dfnName, const std::string &pathName);
+	NLGEORGES::IEditDocument *createDocument (const char *dfnName, const char *pathName);
 	virtual void getSearchPath (std::string &searchPath);
 	virtual NLMISC::CConfigFile		&getConfigFile()				{	return ConfigFile; }
 
@@ -153,10 +153,10 @@ public:
 	CImageListEx		ImageList;
 
 	// Get a template form
-	CMultiDocTemplate	*getFormDocTemplate (const std::string &dfnName);
+	CMultiDocTemplate	*getFormDocTemplate (const char *dfnName);
 
-	void	saveWindowState (const CWnd *wnd, const std::string &name, bool controlBar);
-	void	loadWindowState (CWnd *wnd, const std::string &name, bool changeShowWindow, bool controlBar);
+	void	saveWindowState (const CWnd *wnd, const char *name, bool controlBar);
+	void	loadWindowState (CWnd *wnd, const char *name, bool changeShowWindow, bool controlBar);
 
 // Overrides
 	// ClassWizard generated virtual function overrides
@@ -176,8 +176,8 @@ public:
 	void	releasePlugins ();
 
 	// Dialog function
-	void	outputError (const std::string &message);
-	bool	yesNo (const std::string &message);
+	void	outputError (const char* message);
+	bool	yesNo (const char* message);
 	bool	getColor (NLMISC::CRGBA &color);
 
 	// Browse an URL
diff --git a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
index 7380a3d31..baef40640 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
@@ -460,7 +460,7 @@ void CMemoryComboBox::refreshStrings ()
 
 // ***************************************************************************
 
-void CMemoryComboBox::setRegisterAdress(const std::string &registerAdress)
+void CMemoryComboBox::setRegisterAdress (const char *registerAdress)
 {
 	RegisterAdress = registerAdress;
 	refreshStrings ();
@@ -468,7 +468,7 @@ void CMemoryComboBox::setRegisterAdress(const std::string &registerAdress)
 
 // ***************************************************************************
 
-void CMemoryComboBox::addCommand (const std::string &commandLabel, uint commandId)
+void CMemoryComboBox::addCommand (const char* commandLabel, uint commandId)
 {
 	Commands.push_back (CCommand ());
 	Commands[Commands.size()-1].Label = commandLabel;
diff --git a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
index 446c2a609..be999d252 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
@@ -48,9 +48,9 @@ public:
 	void onCancel ();
 	void create (DWORD style, const RECT &rect, CWnd *parent, UINT nId, const char *registerAdress, int memoryCount);
 	void create (DWORD style, const RECT &rect, CWnd *parent, UINT nId);
-	void setRegisterAdress(const std::string &registerAdress);
+	void setRegisterAdress (const char *registerAdress);
 	void clearCommand ();
-	void addCommand(const std::string &commandLabel, uint commandId);
+	void addCommand (const char* commandLabel, uint commandId);
 	void clearStaticStrings ();
 	void addStaticStrings (const char* strings);
 	uint getCommandCount () const;

From 01d5edd47bb829b23628e1dfa05200c6cdc2cdb5 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Tue, 30 Apr 2019 13:07:57 +0800
Subject: [PATCH 28/75] Fixing unicode in georges edit dll

---
 .../leveldesign/georges_dll/child_frm.cpp     |  2 +-
 .../leveldesign/georges_dll/dfn_dialog.cpp    |  4 +-
 .../leveldesign/georges_dll/dfn_dialog.h      |  4 +-
 .../leveldesign/georges_dll/georges_edit.cpp  | 66 +++++++++----------
 .../leveldesign/georges_dll/georges_edit.h    |  8 +--
 .../georges_dll/georges_edit_doc.cpp          | 32 ++++-----
 6 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/georges_dll/child_frm.cpp b/code/ryzom/tools/leveldesign/georges_dll/child_frm.cpp
index 37a85329d..9f388be4f 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/child_frm.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/child_frm.cpp
@@ -63,7 +63,7 @@ BOOL CChildFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/,
 	}
 
 	// Load state
-	theApp.loadWindowState (this, "child", true, false);
+	theApp.loadWindowState (this, _T("child"), true, false);
 
 	return TRUE;
 }
diff --git a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
index 1ddbe46b1..72a446870 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
@@ -385,7 +385,7 @@ void CDfnEditListCtrl::getNewItemText (uint item, uint subItem, std::string &ret
 
 // ***************************************************************************
 
-void CDfnEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::string &filter)
+void CDfnEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter)
 {
 	if (subItem == 2)
 	{
@@ -621,7 +621,7 @@ void CDfnParentEditListCtrl::getNewItemText (uint item, uint subItem, std::strin
 
 // ***************************************************************************
 
-void CDfnParentEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::string &filter)
+void CDfnParentEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter)
 {
 	filter = DfnFilter;
 	defDir = theApp.RootSearchPath;
diff --git a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h
index 174001aaa..785d64539 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h
@@ -36,7 +36,7 @@ class CDfnParentEditListCtrl : public CEditListCtrl
 	CEditListCtrl::TItemEdit	getItemEditMode (uint item, uint subItem);
 	void						getMemComboBoxProp (uint item, uint subItem, std::string &regAdr, bool &browse);
 	void						getNewItemText (uint item, uint subItem, std::string &ret);
-	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::string &filter);
+	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter);
 public:
 	class CDfnDialog			*Dialog;
 };
@@ -47,7 +47,7 @@ class CDfnEditListCtrl : public CEditListCtrl
 	void						getComboBoxStrings (uint item, uint subItem, std::vector<std::string> &retStrings);
 	void						getMemComboBoxProp (uint item, uint subItem, std::string &regAdr, bool &browse);
 	void						getNewItemText (uint item, uint subItem, std::string &ret);
-	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::string &filter);
+	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter);
 	void						onItemChanged (uint item, uint subItem);
 public:
 	class CDfnDialog			*Dialog;
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
index effc20681..9b62e3a1a 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
@@ -39,8 +39,8 @@ using namespace NLGEORGES;
 using namespace std;
 
 
-const char* TypeFilter = "Type Files (*.typ)|*.typ|All Files (*.*)|*.*||";
-const char* DfnFilter = "Form Definition Files (*.dfn)|*.dfn|All Files (*.*)|*.*||";
+const TCHAR* TypeFilter = _T("Type Files (*.typ)|*.typ|All Files (*.*)|*.*||");
+const TCHAR* DfnFilter = _T("Form Definition Files (*.dfn)|*.dfn|All Files (*.*)|*.*||");
 CSplashScreen* splashScreen=new CSplashScreen;
 /////////////////////////////////////////////////////////////////////////////
 // CGeorgesEditApp
@@ -711,9 +711,9 @@ bool CGeorgesEditApp::getColor (NLMISC::CRGBA &color)
 bool CGeorgesEditApp::yesNo (const char* message)
 {
 	if (m_pMainWnd)
-		return m_pMainWnd->MessageBox (message, _T("Georges Edit"), MB_YESNO|MB_ICONQUESTION) != IDNO;
+		return m_pMainWnd->MessageBox (utf8ToTStr(message), _T("Georges Edit"), MB_YESNO|MB_ICONQUESTION) != IDNO;
 	else
-		return MessageBox (NULL, message, _T("Georges Edit"), MB_YESNO|MB_ICONQUESTION)  != IDNO;
+		return MessageBox (NULL, utf8ToTStr(message), _T("Georges Edit"), MB_YESNO|MB_ICONQUESTION)  != IDNO;
 }
 
 void CGeorgesEditApp::loadPlugins ()
@@ -829,10 +829,10 @@ NLGEORGES::IEditDocument *CGeorgesEditApp::createDocument (const char *dfnName,
 			// Set the filename
 			if (strcmp (pathName, "") != 0)
 			{
-				doc->SetPathName ( pathName, FALSE );
+				doc->SetPathName (utf8ToTStr(pathName), FALSE );
 
 				// Create the file
-				doc->OnSaveDocument( pathName );
+				doc->OnSaveDocument(utf8ToTStr(pathName) );
 			}
 
 			// Init the frame
@@ -908,10 +908,10 @@ LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata)
 
     if (retval == ERROR_SUCCESS) 
 	{
-        long datasize = MAX_PATH;
-        char data[MAX_PATH];
+        long datasize = MAX_PATH * sizeof(TCHAR);
+        TCHAR data[MAX_PATH];
         RegQueryValue(hkey, NULL, data, &datasize);
-        lstrcpy(retdata,data);
+        lstrcpy(retdata, data);
         RegCloseKey(hkey);
     }
 
@@ -936,7 +936,7 @@ void CGeorgesEditApp::OnViewRefresh()
 	}
 }
 
-void CGeorgesEditApp::saveWindowState (const CWnd *wnd, const char *name, bool controlBar)
+void CGeorgesEditApp::saveWindowState (const CWnd *wnd, const TCHAR *name, bool controlBar)
 {
 	HKEY hKey;
 	nlverify (RegCreateKey (HKEY_CURRENT_USER, _T(GEORGES_EDIT_BASE_REG_KEY "\\Windows states"), &hKey) == ERROR_SUCCESS);
@@ -952,7 +952,7 @@ void CGeorgesEditApp::saveWindowState (const CWnd *wnd, const char *name, bool c
 	nlverify (RegCloseKey (hKey) == ERROR_SUCCESS);
 }
 
-void CGeorgesEditApp::loadWindowState (CWnd *wnd, const char *name, bool mdiChildWnd, bool controlBar)
+void CGeorgesEditApp::loadWindowState (CWnd *wnd, const TCHAR *name, bool mdiChildWnd, bool controlBar)
 {
 	HKEY hKey;
 	if (RegOpenKey (HKEY_CURRENT_USER, _T(GEORGES_EDIT_BASE_REG_KEY "\\Windows states"), &hKey) == ERROR_SUCCESS)
@@ -993,20 +993,20 @@ void CGeorgesEditApp::saveState ()
 	// Save the main window state
 	nlassert (m_pMainWnd);
 	if (ResizeMain)
-		saveWindowState (m_pMainWnd, "main", false);
+		saveWindowState (m_pMainWnd, _T("main"), false);
 
-	saveWindowState (&((CMainFrame*)m_pMainWnd)->FileBrowser, "browser", true);
-	saveWindowState (&((CMainFrame*)m_pMainWnd)->OutputConsole, "output", true);
+	saveWindowState (&((CMainFrame*)m_pMainWnd)->FileBrowser, _T("browser"), true);
+	saveWindowState (&((CMainFrame*)m_pMainWnd)->OutputConsole, _T("output"), true);
 }
 
 void CGeorgesEditApp::loadState ()
 {
 	nlassert (m_pMainWnd);
 	if (ResizeMain)
-		loadWindowState (m_pMainWnd, "main", false, false);
+		loadWindowState (m_pMainWnd, _T("main"), false, false);
 
-	loadWindowState (&((CMainFrame*)m_pMainWnd)->FileBrowser, "browser", false, true);
-	loadWindowState (&((CMainFrame*)m_pMainWnd)->OutputConsole, "output", false, true);
+	loadWindowState (&((CMainFrame*)m_pMainWnd)->FileBrowser, _T("browser"), false, true);
+	loadWindowState (&((CMainFrame*)m_pMainWnd)->OutputConsole, _T("output"), false, true);
 }
 
 void CGeorgesEditApp::OnFileSaveAll() 
@@ -1060,7 +1060,7 @@ bool CGeorgesEditApp::SerialIntoMemStream (const char *formName, CGeorgesEditDoc
 		{
 			// Get the string
 			CString str = doc->GetPathName ();
-			name = str;
+			name = tStrToUtf8(str);
 			uint pos = name.rfind ('.');
 			if (pos != string::npos)
 			{
@@ -1268,7 +1268,7 @@ bool CGeorgesEditApp::SerialFromMemStream (const char *formName, CGeorgesEditDoc
 		{
 			// Get the string
 			CString str = doc->GetPathName ();
-			nameParent = str;
+			nameParent = tStrToUtf8(str);
 			uint pos = nameParent.rfind ('.');
 			if (pos != string::npos)
 			{
@@ -1423,24 +1423,24 @@ bool CGeorgesEditApp::SerialFromMemStream (const char *formName, CGeorgesEditDoc
 
 BOOL CGeorgesEditApp::OnDDECommand(LPTSTR lpszCommand) 
 {
-	if (strncmp (lpszCommand, "Open", 4) == 0)
+	if (_tcsncmp (lpszCommand, _T("Open"), 4) == 0)
 	{
-		string name = lpszCommand;
+		tstring name = lpszCommand;
 		name = name.substr (6, name.size ()-8);
 		OpenDocumentFile  (name.c_str ());
 	}
-	else if (strncmp (lpszCommand, "Georges Copy", 4) == 0)
+	else if (_tcsncmp(lpszCommand, _T("Georges Copy"), 4) == 0)
 	{
 		// Get ext name
-		string name = lpszCommand;
+		tstring name = lpszCommand;
 		name = name.substr (6, name.size ()-8);
 
 		// Get the extension
-		std::string ext = NLMISC::CFile::getExtension(name);
+		std::string ext = NLMISC::CFile::getExtension(tStrToUtf8(name.c_str()));
 		string dfnName = ext + ".dfn";
 
 		// Get the doc template
-		CMultiDocTemplate *docTemplate = getFormDocTemplate (dfnName.c_str ());
+		CMultiDocTemplate *docTemplate = getFormDocTemplate(dfnName.c_str());
 
 		if (docTemplate)
 		{
@@ -1452,7 +1452,7 @@ BOOL CGeorgesEditApp::OnDDECommand(LPTSTR lpszCommand)
 			// Create the frame
 			CFrameWnd* pFrame = docTemplate->CreateNewFrame(doc, NULL);
 			nlassert (pFrame);
-			if (doc->loadFormFile (name.c_str ()))
+			if (doc->loadFormFile(tStrToUtf8(name.c_str()).c_str()))
 			{
 
 				doc->updateDocumentStructure ();
@@ -1491,21 +1491,21 @@ BOOL CGeorgesEditApp::OnDDECommand(LPTSTR lpszCommand)
 			outputError (tmp);
 		}
 	}
-	else if (strncmp (lpszCommand, "Derive", 6) == 0)
+	else if (_tcsncmp(lpszCommand, _T("Derive"), 6) == 0)
 	{
 		// Get ext name
-		string name = lpszCommand;
+		tstring name = lpszCommand;
 		name = name.substr (8, name.size ()-10);
 
 		// Get the extension
-		std::string ext = NLMISC::CFile::getExtension(name);
+		std::string ext = NLMISC::CFile::getExtension(tStrToUtf8(name.c_str()));
 		string dfnName = ext + ".dfn";
 
 		// Create a document
 		CGeorgesEditDocForm *doc = (CGeorgesEditDocForm*)createDocument (dfnName.c_str (), "");
 		if (doc)
 		{
-			std::string nameFile = NLMISC::CFile::getFilename(name);
+			std::string nameFile = NLMISC::CFile::getFilename(tStrToUtf8(name.c_str()));
 			doc->addParent (nameFile.c_str());
 			doc->updateDocumentStructure ();
 			doc->UpdateAllViews (NULL);
@@ -1517,14 +1517,14 @@ BOOL CGeorgesEditApp::OnDDECommand(LPTSTR lpszCommand)
 			outputError (tmp);
 		}
 	}
-	else if (strncmp (lpszCommand, "CreateForm", 10) == 0)
+	else if (_tcsncmp(lpszCommand, _T("CreateForm"), 10) == 0)
 	{
 		// Get ext name
-		string name = lpszCommand;
+		tstring name = lpszCommand;
 		name = name.substr (10, name.size ()-12);
 
 		// Get the extension
-		std::string dfnName = NLMISC::CFile::getFilename(name);
+		std::string dfnName = NLMISC::CFile::getFilename(tStrToUtf8(name.c_str()));
 
 		// Create a document
 		CGeorgesEditDocForm *doc = (CGeorgesEditDocForm*)createDocument (dfnName.c_str (), "");
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h
index 6b233f590..9232e688a 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.h
@@ -41,8 +41,8 @@
 #define GEORGES_EDIT_BASE_REG_KEY "Software\\Nevrax\\Georges Edit"
 #define GEORGES_EDIT_BROWSE_LABEL "--- Browse..."
 
-extern const char* TypeFilter;
-extern const char* DfnFilter;
+extern const TCHAR* TypeFilter;
+extern const TCHAR* DfnFilter;
 
 class CGeorgesEditDoc;
 
@@ -155,8 +155,8 @@ public:
 	// Get a template form
 	CMultiDocTemplate	*getFormDocTemplate (const char *dfnName);
 
-	void	saveWindowState (const CWnd *wnd, const char *name, bool controlBar);
-	void	loadWindowState (CWnd *wnd, const char *name, bool changeShowWindow, bool controlBar);
+	void	saveWindowState (const CWnd *wnd, const TCHAR *name, bool controlBar);
+	void	loadWindowState (CWnd *wnd, const TCHAR *name, bool changeShowWindow, bool controlBar);
 
 // Overrides
 	// ClassWizard generated virtual function overrides
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp
index 0bc32cfc9..01f7b6f8e 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp
@@ -223,10 +223,10 @@ BOOL CGeorgesEditDocForm::OnNewDocument()
 		string defFilename = theApp.RootSearchPath;
 		defFilename += "*.dfn";
 
-		CFileDialog dlgFile (TRUE, _T("*.dfn"), defFilename.c_str (), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, DfnFilter, theApp.m_pMainWnd);
+		CFileDialog dlgFile(TRUE, _T("*.dfn"), utf8ToTStr(defFilename.c_str()), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, DfnFilter, theApp.m_pMainWnd);
 		if (dlgFile.DoModal () == IDOK)
 		{
-			if (initDocument (dlgFile.GetFileName (), true))
+			if (initDocument(tStrToUtf8(dlgFile.GetFileName()).c_str(), true))
 				return TRUE;
 		}
 	}
@@ -491,7 +491,7 @@ BOOL CGeorgesEditDoc::OnOpenDocument(LPCTSTR lpszPathName)
 		try
 		{
 			// Read the form with the loader
-			Type = FormLoader.loadType (lpszPathName);
+			Type = FormLoader.loadType(tStrToUtf8(lpszPathName));
 			if (!Type)
 			{
 				char msg[512];
@@ -517,11 +517,11 @@ BOOL CGeorgesEditDoc::OnOpenDocument(LPCTSTR lpszPathName)
 		try
 		{
 			// Read the form with the loader
-			Dfn = FormLoader.loadFormDfn (lpszPathName, true);
+			Dfn = FormLoader.loadFormDfn (tStrToUtf8(lpszPathName), true);
 			if (!Dfn)
 			{
 				char msg[512];
-				smprintf (msg, 512, "Error while loading Dfn file %s", lpszPathName);
+				smprintf (msg, 512, "Error while loading Dfn file %s", tStrToUtf8(lpszPathName).c_str());
 				theApp.outputError (msg);
 				return FALSE;
 			}
@@ -554,13 +554,13 @@ BOOL CGeorgesEditDoc::OnOpenDocument(LPCTSTR lpszPathName)
 				if (theApp.getFormDocTemplate (dfnName.c_str ()) == NULL)
 				{
 					char message[512];
-					smprintf (message, 512, "Can't open the file '%s'.", lpszPathName);
+					smprintf (message, 512, "Can't open the file '%s'.", tStrToUtf8(lpszPathName).c_str());
 					theApp.outputError (message);
 					return FALSE;
 				}
 				
 				// Read the form with the loader
-				if (!loadFormFile (lpszPathName))
+				if (!loadFormFile (tStrToUtf8(lpszPathName).c_str()))
 					return FALSE;
 
 				if (theApp.ExeStandalone)
@@ -743,7 +743,7 @@ BOOL CGeorgesEditDoc::OnSaveDocument(LPCTSTR lpszPathName)
 
 	// Open the filt
 	COFile file;
-	if (file.open (lpszPathName))
+	if (file.open(tStrToUtf8(lpszPathName)))
 	{
 		try
 		{
@@ -778,7 +778,7 @@ BOOL CGeorgesEditDoc::OnSaveDocument(LPCTSTR lpszPathName)
 					Dfn->Header.MinorVersion++;
 					flushValueChange ();
 				}
-				Dfn->write (xmlStream.getDocument (), lpszPathName);
+				Dfn->write (xmlStream.getDocument (), tStrToUtf8(lpszPathName));
 				modify (NULL, NULL, false);
 				UpdateAllViews (NULL);
 				return TRUE;
@@ -793,11 +793,11 @@ BOOL CGeorgesEditDoc::OnSaveDocument(LPCTSTR lpszPathName)
 					((CForm*)(UForm*)Form)->Header.MinorVersion++;				
 					flushValueChange ();
 				}
-				((CForm*)(UForm*)Form)->write (xmlStream.getDocument (), lpszPathName);
-				if (strcmp (xmlStream.getErrorString (), "") != 0)
+				((CForm*)(UForm*)Form)->write (xmlStream.getDocument (), tStrToUtf8(lpszPathName));
+				if (strcmp(xmlStream.getErrorString().c_str(), "") != 0)
 				{
 					char message[512];
-					smprintf (message, 512, "Error while saving file: %s", xmlStream.getErrorString ());
+					smprintf (message, 512, "Error while saving file: %s", xmlStream.getErrorString().c_str());
 					theApp.outputError (message);
 				}
 				modify (NULL, NULL, false);
@@ -1122,7 +1122,7 @@ void CGeorgesEditDoc::getFilename (std::string &pathname)
 {
 	AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
-	pathname = (const char*)GetPathName ();
+	pathname = tStrToUtf8(GetPathName());
 }
 
 // ***************************************************************************
@@ -1131,7 +1131,7 @@ void CGeorgesEditDoc::getTitle (std::string &title)
 {
 	AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
-	title = (const char*)GetTitle ();
+	title = tStrToUtf8(GetTitle());
 }
 
 // ***************************************************************************
@@ -1327,11 +1327,11 @@ void CGeorgesEditDoc::setModifiedState (bool modified)
 	}
 	else
 	{
-		string title = (const char*)GetTitle ();
+		string title = tStrToUtf8(GetTitle());
 		if ( (title.size ()>=2) && (title[title.size()-1] == '*') && (title[title.size()-2] == ' ') )
 		{
 			title.resize (title.size () - 2);
-			SetTitle (title.c_str());
+			SetTitle (utf8ToTStr(title));
 		}
 	}
 }

From 556806715e733c199573bcd412f9c6c538425ac1 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Tue, 30 Apr 2019 13:16:05 +0800
Subject: [PATCH 29/75] Fixing unicode in georges edit dll

---
 .../georges_dll/georges_implementation.cpp    |  6 ++--
 .../leveldesign/georges_dll/header_dialog.cpp | 32 +++++++++----------
 .../leveldesign/georges_dll/icon_wnd.cpp      |  9 +++---
 .../leveldesign/georges_dll/imagelist_ex.cpp  |  4 +--
 4 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp
index 2ac3ed596..9e0b30f6e 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp
@@ -579,12 +579,12 @@ void CGeorgesImpl::LoadDocument( const std::string& _sxfullname )
 	AFX_MANAGE_STATE(AfxGetStaticModuleState());
 	try
 	{
-		theApp.OpenDocumentFile(_sxfullname.c_str());
+		theApp.OpenDocumentFile(utf8ToTStr(_sxfullname));
 	}
 	catch (const NLMISC::Exception &e)
 	{
 		std::string tmp = std::string(e.what()) + "(" + _sxfullname + ")";
-		theApp.m_pMainWnd->MessageBox(tmp.c_str(), "Georges_Lib", MB_ICONERROR | MB_OK);
+		theApp.m_pMainWnd->MessageBox(utf8ToTStr(tmp), _T("Georges_Lib"), MB_ICONERROR | MB_OK);
 	}
 }
 
@@ -666,7 +666,7 @@ IGeorges* IGeorges::getInterface (int version)
 	// Check version number
 	if (version != GEORGES_VERSION)
 	{
-		MessageBox (NULL, "Bad version of georges.dll.", "Georges", MB_ICONEXCLAMATION|MB_OK);
+		MessageBox(NULL, _T("Bad version of georges.dll."), _T("Georges"), MB_ICONEXCLAMATION | MB_OK);
 		return NULL;
 	}
 	else
diff --git a/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp
index 8bdf3e165..ee1385216 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp
@@ -86,20 +86,20 @@ BOOL CHeaderDialog::OnInitDialog()
 
 	// Create the version
 	setStaticSize (currentPos);
-	char versionText[512];
-	smprintf (versionText, 512, "Version %d.%d", 0, 0);
+	CString versionText;
+	versionText.Format(_T("Version %d.%d"), 0, 0);
 	LabelVersion.Create (versionText, WS_VISIBLE, currentPos, this);
 	initWidget (LabelVersion);
 	getNextPosLabel (currentPos);
 
 	setButtonSize (currentPos, SmallWidget);
-	IncrementVersion.Create ("Increment Version", WS_VISIBLE|WS_TABSTOP, currentPos, this, BtIncrement);
+	IncrementVersion.Create (_T("Increment Version"), WS_VISIBLE|WS_TABSTOP, currentPos, this, BtIncrement);
 	initWidget (IncrementVersion);
 	getNextPos (currentPos);
 
 	// Create the state combo
 	setStaticSize (currentPos);
-	LabelState.Create ("State:", WS_VISIBLE, currentPos, this);
+	LabelState.Create (_T("State:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelState);
 	getNextPosLabel (currentPos);
 
@@ -109,30 +109,30 @@ BOOL CHeaderDialog::OnInitDialog()
 	ComboState.Create (WS_VISIBLE|CBS_DROPDOWNLIST|WS_TABSTOP, pos, this, CbState);
 	uint item;
 	for (item=0; item<CFileHeader::StateCount; item++)
-		ComboState.InsertString (-1, CFileHeader::getStateString ((CFileHeader::TState)item));
+		ComboState.InsertString (-1, utf8ToTStr(CFileHeader::getStateString ((CFileHeader::TState)item)));
 	ComboState.SetCurSel (0);
 	initWidget (ComboState);
 	getNextPos (currentPos);
 
 	// Default value
 	setStaticSize (currentPos);
-	LabelComments.Create ("Comments:", WS_VISIBLE, currentPos, this);
+	LabelComments.Create (_T("Comments:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelComments);
 	getNextPosLabel (currentPos);
 
 	setBigEditSize (currentPos, SmallWidget);
-	Comments.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), "", WS_VSCROLL|ES_OEMCONVERT|ES_MULTILINE|ES_WANTRETURN|WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL|ES_AUTOVSCROLL, currentPos, this, EdComments);
+	Comments.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), WS_VSCROLL|ES_OEMCONVERT|ES_MULTILINE|ES_WANTRETURN|WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_AUTOHSCROLL|ES_AUTOVSCROLL, currentPos, this, EdComments);
 	initWidget (Comments);
 	getNextPos (currentPos);
 
 	// Min value
 	setStaticSize (currentPos);
-	LabelLog.Create ("Log:", WS_VISIBLE, currentPos, this);
+	LabelLog.Create (_T("Log:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelLog);
 	getNextPosLabel (currentPos);
 
 	setBigEditSize (currentPos, SmallWidget);
-	Log.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), "", WS_VSCROLL|ES_READONLY|ES_MULTILINE|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|ES_AUTOVSCROLL, currentPos, this, EdLog);
+	Log.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), WS_VSCROLL|ES_READONLY|ES_MULTILINE|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|ES_AUTOVSCROLL, currentPos, this, EdLog);
 	initWidget (Log);
 	getNextPos (currentPos);
 
@@ -244,8 +244,8 @@ void CHeaderDialog::getFromDocument (const NLGEORGES::CFileHeader &header)
 	{
 		// Nel standard version number
 		ComboState.SetCurSel (header.State);
-		char name[512];
-		smprintf (name, 512, "Version %d.%d", header.MajorVersion, header.MinorVersion);
+		CString name;
+		name.Format(_T("Version %d.%d"), header.MajorVersion, header.MinorVersion);
 		LabelVersion.SetWindowText (name);
 
 		// Set comments
@@ -276,16 +276,16 @@ void CHeaderDialog::setVersionToDocument ()
 		uint v0, v1;
 		CString str;
 		LabelVersion.GetWindowText (str);
-		if (sscanf ((const char*)str, "Version %d.%d", &v0, &v1)==2)
+		if (sscanf (tStrToUtf8(str).c_str(), "Version %d.%d", &v0, &v1)==2)
 		{
 			v0++;
 			v1=0;
-			char name[512];
-			smprintf (name, 512, "Version %d.%d", v0, v1);
+			CString name;
+			name.Format(_T("Version %d.%d"), v0, v1);
 			LabelVersion.SetWindowText (name);
 
 			// Modify docuemnt
-			doc->modify (new CActionString (IAction::HeaderVersion, name, *doc, "",  "",
+			doc->modify(new CActionString(IAction::HeaderVersion, tStrToUtf8(name).c_str(), *doc, "",  "",
 				doc->getLeftView ()->getCurrentSelectionId (), 0));
 		}
 	}
@@ -299,7 +299,7 @@ void CHeaderDialog::setCommentsToDocument ()
 		CGeorgesEditDocSub *current = doc->getSelectedObject ();
 		CString str;
 		Comments.GetWindowText (str);
-		doc->modify (new CActionString (IAction::HeaderComments, str, *doc, "",  "",
+		doc->modify(new CActionString(IAction::HeaderComments, tStrToUtf8(str).c_str(), *doc, "",  "",
 			doc->getLeftView ()->getCurrentSelectionId (), 0));
 	}
 }
diff --git a/code/ryzom/tools/leveldesign/georges_dll/icon_wnd.cpp b/code/ryzom/tools/leveldesign/georges_dll/icon_wnd.cpp
index 5a28d65e6..fd657fcc7 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/icon_wnd.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/icon_wnd.cpp
@@ -85,7 +85,7 @@ void CIconWnd::create (DWORD wStyle, RECT &pos, CWnd *parent, uint dialogIndex)
 	LPCTSTR className = AfxRegisterWndClass(CS_OWNDC); 
 
 	// Create this window
-	CWnd::Create(className, "empty", wStyle, pos, parent, dialogIndex);
+	CWnd::Create(className, _T("empty"), wStyle, pos, parent, dialogIndex);
 }
 
 bool CIconWnd::updateStr()
@@ -283,14 +283,15 @@ void CIconWnd::addIconLayer(NLMISC::CBitmap &dst, const std::string iconStr, con
 
 bool CIconWnd::updateWnd(CWnd *pWnd, std::string &str)
 {
-	char buffer[512];
+	TCHAR buffer[512];
 
 	if (pWnd)
 	{
 		pWnd->GetWindowText(buffer, 512);
-		if (buffer != str)
+		std::string buf = tStrToUtf8(buffer);
+		if (buf != str)
 		{
-			str = buffer;
+			str = buf;
 			return true;
 		}
 	}
diff --git a/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp b/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp
index 590e98a25..0de9b99b0 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp
@@ -27,7 +27,7 @@ using namespace NLMISC;
 
 #pragma warning (disable : 4786)
 
-BOOL CALLBACK EnumResLangProc(HMODULE hModule, LPCSTR lpszType, LPCSTR lpszName, WORD wIDLanguage, 
+BOOL CALLBACK EnumResLangProc(HMODULE hModule, LPCTSTR lpszType, LPCTSTR lpszName, WORD wIDLanguage, 
 							  LONG_PTR lParam)
 {
 	set<HRSRC> *iconNames = (set<HRSRC>*)lParam;
@@ -96,7 +96,7 @@ void CImageListEx::addResourceIcon (const char *filename)
 		int height = imageInfo.rcImage.bottom - imageInfo.rcImage.top;
 		
 		// Load the icon
-		HICON handle = (HICON) LoadImage (NULL, filename, IMAGE_ICON, width, height, LR_COLOR|LR_LOADFROMFILE);
+		HICON handle = (HICON) LoadImage (NULL, utf8ToTStr(filename), IMAGE_ICON, width, height, LR_COLOR|LR_LOADFROMFILE);
 		if (handle)
 		{
 			// Copy the icon

From 883ee21a176dd2a186a00077934012490cbfa340 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Tue, 30 Apr 2019 13:26:59 +0800
Subject: [PATCH 30/75] Fixing unicode in georges edit dll

---
 .../georges_dll/edit_list_ctrl.cpp            |  4 +--
 .../leveldesign/georges_dll/form_dialog.cpp   |  8 +++---
 .../leveldesign/georges_dll/form_dialog.h     |  2 +-
 .../leveldesign/georges_dll/left_view.cpp     | 10 +++----
 .../leveldesign/georges_dll/main_frm.cpp      | 12 ++++-----
 .../georges_dll/memory_combo_box.cpp          | 27 ++++++++++---------
 .../georges_dll/memory_combo_box.h            |  6 ++---
 .../georges_dll/output_console_dlg.cpp        |  2 +-
 .../leveldesign/georges_dll/reg_shell_ext.cpp |  4 +--
 9 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp b/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp
index 0b16abd4f..bad4b8a1e 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp
@@ -69,7 +69,7 @@ bool CEditListCtrl::create (DWORD wStyle, RECT &rect, CWnd *parent, uint dialog_
 			Edit.SetFont (ListCtrl.GetFont());
 			Combo.Create (WS_BORDER|CBS_DROPDOWNLIST, rect, &ListCtrl, IdCombo);
 			Combo.SetFont (ListCtrl.GetFont());
-			MemCombo.create (WS_CHILD, rect, &ListCtrl, IdMemCombo, "", theApp.RememberListSize);
+			MemCombo.create (WS_CHILD, rect, &ListCtrl, IdMemCombo, _T(""), theApp.RememberListSize);
 			MemCombo.SetFont (ListCtrl.GetFont());
 			return true;
 		}
@@ -475,7 +475,7 @@ void CEditListCtrl::editItem (uint item, uint subitem)
 		string retString;
 		bool browse;
 		getMemComboBoxProp (Item, SubItem, retString, browse);
-		MemCombo.setRegisterAdress (retString.c_str ());
+		MemCombo.setRegisterAdress (utf8ToTStr(retString));
 		MemCombo.clearCommand ();
 		if (browse)
 			MemCombo.addCommand (GEORGES_EDIT_BROWSE_LABEL, CmdBrowse);
diff --git a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
index 8cf257035..d86cc21bd 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
@@ -165,7 +165,7 @@ CWnd* CFormDialog::addTypeWidget (const NLGEORGES::CType &type, uint elmIndex, c
 
 			// Create a reg key
 			string tfn = typeFilename;
-			string key = GEORGES_EDIT_BASE_REG_KEY"\\"+strlwr (typeFilename)+" MemCombo";
+			tstring key = utf8ToTStr(GEORGES_EDIT_BASE_REG_KEY"\\"+strlwr (typeFilename)+" MemCombo");
 
 			// Create the widget
 			memCombo->create (WS_CHILD|WS_TABSTOP, currentPos, this, WidgetIndexCount, title, key.c_str(), type.UIType==CType::EditSpin, type.UIType==CType::FileBrowser, filenameExt);
@@ -251,7 +251,7 @@ void CFormDialog::getVirtualDfnFromDocument (const NLGEORGES::CFormDfn *_dfn, co
 
 			// Create the widget
 			memCombo->create (WS_CHILD|WS_TABSTOP, currentPos, this, WidgetIndexCount, "Dfn:", 
-				GEORGES_EDIT_BASE_REG_KEY"\\Virtual Dfn MemCombo", false, true, "*.dfn");
+				_T(GEORGES_EDIT_BASE_REG_KEY) _T("\\Virtual Dfn MemCombo"), false, true, "*.dfn");
 
 			// Get from document
 			memCombo->getFromDocument (*doc->getFormPtr ());
@@ -462,7 +462,7 @@ void CFormDialog::getArrayFromDocument (const char *structName, uint structId, u
 
 			// Create the widget
 			memCombo->create (WS_CHILD|WS_TABSTOP, currentPos, this, WidgetIndexCount, "Array size:", 
-				GEORGES_EDIT_BASE_REG_KEY"\\Array Size MemCombo", true, false, NULL);
+				_T(GEORGES_EDIT_BASE_REG_KEY) _T("\\Array Size MemCombo"), true, false, NULL);
 
 			// Get from document
 			memCombo->getFromDocument (*doc->getFormPtr ());
@@ -1541,7 +1541,7 @@ CFormMemCombo::~CFormMemCombo ()
 
 // ***************************************************************************
 
-void CFormMemCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, uint &dialog_index, const char *label, const char *reg, bool useSpinner, bool fileBrowser, const char *filenameExt)
+void CFormMemCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, uint &dialog_index, const char *label, const TCHAR *reg, bool useSpinner, bool fileBrowser, const char *filenameExt)
 {
 	// Get the doc
 	CGeorgesEditDoc *doc = Dialog->View->GetDocument ();
diff --git a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.h b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.h
index cb9d29bab..d3afef083 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.h
@@ -207,7 +207,7 @@ public:
 	bool			FileBrowser;
 
 	// Create the widget
-	void create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, uint &dialog_index, const char *label, const char *reg, bool spinner, bool fileBrowser, const char *filenameExt);
+	void create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, uint &dialog_index, const char *label, const TCHAR *reg, bool spinner, bool fileBrowser, const char *filenameExt);
 
 	// From IFormWidget
 	void onOk ();
diff --git a/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp b/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp
index 5f699dafe..7101680dd 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp
@@ -109,11 +109,11 @@ void CLeftView::getSubObject (CGeorgesEditDocSub *subObject, HTREEITEM parent, H
 	if (!item)
 	{
 		int itemImage = subObject->getItemImage (GetDocument());
-		item = TreeCtrl.InsertItem (subObject->getName ().c_str(), itemImage, itemImage, parent);
+		item = TreeCtrl.InsertItem (utf8ToTStr(subObject->getName()), itemImage, itemImage, parent);
 	}
 
 	// Set name
-	TreeCtrl.SetItemText (item, subObject->getName ().c_str());
+	TreeCtrl.SetItemText (item, utf8ToTStr(subObject->getName()));
 
 	// Set item data
 	TreeCtrl.SetItemData (item, (DWORD)subObject);
@@ -351,8 +351,8 @@ BOOL CLeftView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
 								{
 									// Change the node name
 									TreeCtrl.SetItemText (ptvdi->item.hItem, ptvdi->item.pszText);
-									doc->modify (new CActionString (IAction::FormArrayRename, ptvdi->item.pszText, *doc, 
-										subObject->getFormName ().c_str (), toString (subObject->getIdInParent ()).c_str(), 
+									doc->modify (new CActionString(IAction::FormArrayRename, tStrToUtf8(ptvdi->item.pszText).c_str(), *doc, 
+										subObject->getFormName().c_str(), toString (subObject->getIdInParent()).c_str(), 
 										doc->getLeftView ()->getCurrentSelectionId (), subObject->getSlot ()));
 									return TRUE;
 								}
@@ -878,7 +878,7 @@ void CLeftView::OnDelete()
 		CEdit *edit = TreeCtrl.GetEditControl();
 		if (edit)
 		{
-			edit->SetWindowText ("");
+			edit->SetWindowText (_T(""));
 		}
 		else
 		{
diff --git a/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp b/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp
index 02c06fdde..7239d0f69 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp
@@ -163,7 +163,7 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 	AssertLog->addDisplayer (&Displayer);
 
 	// JC: added LoadBarState
-	LoadBarState("Georges");
+	LoadBarState(_T("Georges"));
 
 	return 0;
 }
@@ -322,7 +322,7 @@ void CMainFrame::OnClose()
 	if (theApp.SaveAllModified())
 	{
 		// JC: added save bar state
-		SaveBarState("Georges");
+		SaveBarState(_T("Georges"));
 		// Save state
 		theApp.saveState ();
 
@@ -436,7 +436,7 @@ void CMainFrame::OnUpdateModules0(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[0].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (name.c_str ());
+		pCmdUI->SetText (utf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[0].Activated);
 	}
 	else
@@ -464,7 +464,7 @@ void CMainFrame::OnUpdateModules1(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[1].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (name.c_str ());
+		pCmdUI->SetText (utf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[1].Activated);
 	}
 	else
@@ -492,7 +492,7 @@ void CMainFrame::OnUpdateModules2(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[2].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (name.c_str ());
+		pCmdUI->SetText (utf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[2].Activated);
 	}
 	else
@@ -520,7 +520,7 @@ void CMainFrame::OnUpdateModules3(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[3].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (name.c_str ());
+		pCmdUI->SetText (utf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[3].Activated);
 	}
 	else
diff --git a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
index baef40640..86204d8f7 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
@@ -43,7 +43,7 @@ CMemoryComboBox::~CMemoryComboBox()
 
 // ***************************************************************************
 
-void CMemoryComboBox::create (DWORD style, const RECT &rect, CWnd *parent, UINT nId, const char *registerAdress, int memoryCount)
+void CMemoryComboBox::create (DWORD style, const RECT &rect, CWnd *parent, UINT nId, const TCHAR *registerAdress, int memoryCount)
 {
 	// Register a window
 	Id = nId;
@@ -52,7 +52,7 @@ void CMemoryComboBox::create (DWORD style, const RECT &rect, CWnd *parent, UINT
 	LPCTSTR clas = AfxRegisterWndClass (0);
 	if (clas)
 	{
-		if (Create (clas, "MemoryComboBox", style, rect, parent, nId))
+		if (Create (clas, _T("MemoryComboBox"), style, rect, parent, nId))
 		{
 			// Create the combo box
 			RECT comboRect;
@@ -95,16 +95,16 @@ bool CMemoryComboBox::getMemory (int slot, std::string &ret)
 {
 	// Open the key
 	HKEY hKey;
-	if (RegOpenKey (HKEY_CURRENT_USER, RegisterAdress.c_str (), &hKey) == ERROR_SUCCESS)
+	if (RegOpenKey(HKEY_CURRENT_USER, RegisterAdress.c_str (), &hKey) == ERROR_SUCCESS)
 	{
 		// Get the value
 		char strSrc[512];
 		smprintf (strSrc, 512, "%d", slot);
-		char str[512];
-		long size = 512;
-		if (RegQueryValue (hKey, strSrc, str, &size) == ERROR_SUCCESS)
+		TCHAR str[512];
+		LONG size = 512 * sizeof(TCHAR);
+		if (RegQueryValue(hKey, utf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
 		{
-			ret = str;
+			ret = tStrToUtf8(str);
 
 			// Close
 			RegCloseKey (hKey);
@@ -132,14 +132,14 @@ void CMemoryComboBox::scrollDown (int start, int end)
 			// Get the old value
 			char strSrc[512];
 			smprintf (strSrc, 512, "%d", i-1);
-			char str[512];
-			long size = 512;
-			if (RegQueryValue (hKey, strSrc, str, &size) == ERROR_SUCCESS)
+			TCHAR str[512];
+			LONG size = 512 * sizeof(TCHAR);
+			if (RegQueryValue (hKey, utf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
 			{
 				// Set the value
 				char strDst[512];
 				smprintf (strDst, 512, "%d", i);
-				RegSetValue (hKey, strDst, REG_SZ, str, size);
+				RegSetValue (hKey, utf8ToTStr(strSrc), REG_SZ, str, size);
 			} 
 		}
 
@@ -157,7 +157,8 @@ void CMemoryComboBox::pushString (const std::string &str)
 	if (RegCreateKey (HKEY_CURRENT_USER, RegisterAdress.c_str (), &hKey) == ERROR_SUCCESS)
 	{
 		// Set the value
-		RegSetValue (hKey, _T("0"), REG_SZ, str.c_str (), str.size ());
+		tstring tstr = utf8ToTStr(str);
+		RegSetValue (hKey, _T("0"), REG_SZ, tstr.c_str (), tstr.size ());
 
 		// Close
 		RegCloseKey (hKey);
@@ -460,7 +461,7 @@ void CMemoryComboBox::refreshStrings ()
 
 // ***************************************************************************
 
-void CMemoryComboBox::setRegisterAdress (const char *registerAdress)
+void CMemoryComboBox::setRegisterAdress (const TCHAR *registerAdress)
 {
 	RegisterAdress = registerAdress;
 	refreshStrings ();
diff --git a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
index be999d252..e0fb2d679 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
@@ -46,9 +46,9 @@ public:
 
 	void onOK ();
 	void onCancel ();
-	void create (DWORD style, const RECT &rect, CWnd *parent, UINT nId, const char *registerAdress, int memoryCount);
+	void create (DWORD style, const RECT &rect, CWnd *parent, UINT nId, const TCHAR *registerAdress, int memoryCount);
 	void create (DWORD style, const RECT &rect, CWnd *parent, UINT nId);
-	void setRegisterAdress (const char *registerAdress);
+	void setRegisterAdress (const TCHAR *registerAdress);
 	void clearCommand ();
 	void addCommand (const char* commandLabel, uint commandId);
 	void clearStaticStrings ();
@@ -59,7 +59,7 @@ public:
 	bool isWnd (const CWnd *wnd) const;
 	void enableAutoCompleteExtension (bool enable, const char * ext);
 
-	std::string			RegisterAdress;
+	std::tstring			RegisterAdress;
 	int					MemoryCount;
 	UINT				Id;
 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp b/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp
index abb81b933..4577f6de8 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp
@@ -98,7 +98,7 @@ void COutputConsoleDlg::outputString (const char *message)
 	{
 		int index = edit->LineIndex(edit->GetLineCount( )-1) + edit->LineLength(edit->GetLineCount( )-1);
 		edit->SetSel (index, index);
-		edit->ReplaceSel (message);
+		edit->ReplaceSel (utf8ToTStr(message));
 	}
 }
 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp b/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp
index c92f2be16..bcb01031f 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp
@@ -21,12 +21,12 @@
 using namespace std;
 using namespace NLMISC;
 
-void deleteKey (HKEY hKey, const char *name)
+void deleteKey (HKEY hKey, const TCHAR *name)
 {
 	HKEY subKey;
 	if (RegOpenKey (hKey, name, &subKey) == ERROR_SUCCESS)
 	{
-		char subName[512];
+		TCHAR subName[512];
 		while (RegEnumKey (subKey, 0, subName, 512) == ERROR_SUCCESS)
 		{
 			deleteKey (subKey, subName);

From d68ac91a4996805b2292ad6df94307eaae6276a6 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 03:09:50 +0800
Subject: [PATCH 31/75] Fix MFC tools build under 64bit, require minimum
 Windows Vista (same as NeL 64bit minimum)

---
 code/nel/tools/3d/object_viewer/std_afx.h                  | 7 ++++++-
 code/nel/tools/3d/object_viewer_exe/std_afx.h              | 7 ++++++-
 code/nel/tools/logic/logic_editor_dll/StdAfx.h             | 7 ++++++-
 code/nel/tools/misc/branch_patcher/StdAfx.h                | 7 ++++++-
 code/nel/tools/misc/data_mirror/StdAfx.h                   | 7 ++++++-
 code/nel/tools/misc/log_analyser/StdAfx.h                  | 7 ++++++-
 code/nel/tools/misc/words_dic/StdAfx.h                     | 7 ++++++-
 code/ryzom/tools/leveldesign/georges_dll/stdafx.h          | 7 ++++++-
 .../leveldesign/georges_plugin_sound/std_sound_plugin.h    | 7 ++++++-
 code/ryzom/tools/leveldesign/mission_compiler_fe/StdAfx.h  | 7 ++++++-
 .../tools/leveldesign/world_editor/world_editor/stdafx.h   | 7 ++++++-
 .../world_editor/world_editor_fauna_graph_plugin/StdAfx.h  | 7 ++++++-
 .../world_editor/world_editor_graph_plugin/StdAfx.h        | 7 ++++++-
 .../world_editor_primitive_plugin/primitive_plugin.h       | 7 ++++++-
 .../world_editor_shard_monitor_plugin/StdAfx.h             | 7 ++++++-
 .../world_editor/world_editor_sound_plugin/StdAfx.h        | 7 ++++++-
 16 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/code/nel/tools/3d/object_viewer/std_afx.h b/code/nel/tools/3d/object_viewer/std_afx.h
index 0cf664508..7bee59e2f 100644
--- a/code/nel/tools/3d/object_viewer/std_afx.h
+++ b/code/nel/tools/3d/object_viewer/std_afx.h
@@ -23,8 +23,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/nel/tools/3d/object_viewer_exe/std_afx.h b/code/nel/tools/3d/object_viewer_exe/std_afx.h
index 953342427..f99ca7a0c 100644
--- a/code/nel/tools/3d/object_viewer_exe/std_afx.h
+++ b/code/nel/tools/3d/object_viewer_exe/std_afx.h
@@ -23,8 +23,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <windows.h>
 
diff --git a/code/nel/tools/logic/logic_editor_dll/StdAfx.h b/code/nel/tools/logic/logic_editor_dll/StdAfx.h
index 7aec1acb4..e173d7608 100644
--- a/code/nel/tools/logic/logic_editor_dll/StdAfx.h
+++ b/code/nel/tools/logic/logic_editor_dll/StdAfx.h
@@ -11,8 +11,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/nel/tools/misc/branch_patcher/StdAfx.h b/code/nel/tools/misc/branch_patcher/StdAfx.h
index b85f337a0..3cd3005ba 100644
--- a/code/nel/tools/misc/branch_patcher/StdAfx.h
+++ b/code/nel/tools/misc/branch_patcher/StdAfx.h
@@ -22,8 +22,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/nel/tools/misc/data_mirror/StdAfx.h b/code/nel/tools/misc/data_mirror/StdAfx.h
index 697fe2127..92105ec09 100644
--- a/code/nel/tools/misc/data_mirror/StdAfx.h
+++ b/code/nel/tools/misc/data_mirror/StdAfx.h
@@ -11,8 +11,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/nel/tools/misc/log_analyser/StdAfx.h b/code/nel/tools/misc/log_analyser/StdAfx.h
index bd3d88df1..e7c2ae30d 100644
--- a/code/nel/tools/misc/log_analyser/StdAfx.h
+++ b/code/nel/tools/misc/log_analyser/StdAfx.h
@@ -27,8 +27,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/nel/tools/misc/words_dic/StdAfx.h b/code/nel/tools/misc/words_dic/StdAfx.h
index 9290bdfce..7f52b209c 100644
--- a/code/nel/tools/misc/words_dic/StdAfx.h
+++ b/code/nel/tools/misc/words_dic/StdAfx.h
@@ -22,8 +22,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/ryzom/tools/leveldesign/georges_dll/stdafx.h b/code/ryzom/tools/leveldesign/georges_dll/stdafx.h
index 91a0d1f9a..cd230a597 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/stdafx.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/stdafx.h
@@ -26,8 +26,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h b/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h
index 8fb65c948..f03a63bdc 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h
@@ -18,8 +18,13 @@
 #define STDAFX_H
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/ryzom/tools/leveldesign/mission_compiler_fe/StdAfx.h b/code/ryzom/tools/leveldesign/mission_compiler_fe/StdAfx.h
index b8693c571..1d127a59b 100644
--- a/code/ryzom/tools/leveldesign/mission_compiler_fe/StdAfx.h
+++ b/code/ryzom/tools/leveldesign/mission_compiler_fe/StdAfx.h
@@ -27,8 +27,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/stdafx.h b/code/ryzom/tools/leveldesign/world_editor/world_editor/stdafx.h
index d8fe8ec31..37dc0bb78 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/stdafx.h
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/stdafx.h
@@ -25,8 +25,13 @@
 #pragma once
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_fauna_graph_plugin/StdAfx.h b/code/ryzom/tools/leveldesign/world_editor/world_editor_fauna_graph_plugin/StdAfx.h
index 58043f752..54dba15f8 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_fauna_graph_plugin/StdAfx.h
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_fauna_graph_plugin/StdAfx.h
@@ -27,8 +27,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <cerrno>
 
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/StdAfx.h b/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/StdAfx.h
index 9beea91c6..dc1d86459 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/StdAfx.h
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/StdAfx.h
@@ -27,8 +27,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <cerrno>
 
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/primitive_plugin.h b/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/primitive_plugin.h
index 8b452cd80..d7a19dc10 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/primitive_plugin.h
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/primitive_plugin.h
@@ -18,8 +18,13 @@
 #define PRIMITIVE_PLUGIN_H
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/StdAfx.h b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/StdAfx.h
index c62c05e5b..13e74ec50 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/StdAfx.h
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/StdAfx.h
@@ -29,8 +29,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/StdAfx.h b/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/StdAfx.h
index 33e78a8b1..04ebecac8 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/StdAfx.h
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/StdAfx.h
@@ -29,8 +29,13 @@
 #endif // _MSC_VER > 1000
 
 #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
 #define NOMINMAX
-#define _WIN32_WINNT 0x0501
+#ifdef _WIN64
+#define _WIN32_WINNT 0x0600
+#else
+#define _WIN32_WINNT 0x0500
+#endif
 
 #include <afxwin.h>         // MFC core and standard components
 #include <afxext.h>         // MFC extensions

From 28a499c95a51c648d2d0355ae45aa8dafed2c7a0 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 03:20:21 +0800
Subject: [PATCH 32/75] Fix bool parsing for non-lowercase values

---
 code/nel/include/nel/misc/string_common.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/code/nel/include/nel/misc/string_common.h b/code/nel/include/nel/misc/string_common.h
index 2839c2bfc..02cafec92 100644
--- a/code/nel/include/nel/misc/string_common.h
+++ b/code/nel/include/nel/misc/string_common.h
@@ -242,6 +242,10 @@ inline bool fromString(const std::string &str, sint64 &val) { bool ret = sscanf(
 inline bool fromString(const std::string &str, float &val) { bool ret = sscanf(str.c_str(), "%f", &val) == 1; if (!ret) val = 0.0f; return ret; }
 inline bool fromString(const std::string &str, double &val) { bool ret = sscanf(str.c_str(), "%lf", &val) == 1; if (!ret) val = 0.0; return ret; }
 
+// Fast string to bool, reliably defined for strings starting with 0, 1, t, T, f, F, y, Y, n, N, anything else is undefined.
+// (str[0] == '1' || (str[0] & 0xD2) == 0x50)
+//  - Kaetemi
+
 inline bool fromString(const std::string &str, bool &val)
 {
 	if (str.length() == 1)
@@ -273,11 +277,12 @@ inline bool fromString(const std::string &str, bool &val)
 	}
 	else
 	{
-		if (str == "true" || str == "yes")
+		std::string strl = toLower(str);
+		if (strl == "true" || strl == "yes")
 		{
 			val = true;
 		}
-		else if (str == "false" || str == "no")
+		else if (strl == "false" || strl == "no")
 		{
 			val = false;
 		}

From a6572f29eb1230371c91d6bcfcbf1747b6700487 Mon Sep 17 00:00:00 2001
From: Inky <jnk@mailoo.org>
Date: Tue, 30 Apr 2019 22:26:25 +0300
Subject: [PATCH 33/75] Backed out changeset f2bc09b6da57

--HG--
branch : develop
---
 code/ryzom/client/src/client_sheets/item_sheet.cpp | 11 +----------
 code/ryzom/client/src/client_sheets/item_sheet.h   |  6 ------
 2 files changed, 1 insertion(+), 16 deletions(-)

diff --git a/code/ryzom/client/src/client_sheets/item_sheet.cpp b/code/ryzom/client/src/client_sheets/item_sheet.cpp
index daac055fe..e13d8e267 100644
--- a/code/ryzom/client/src/client_sheets/item_sheet.cpp
+++ b/code/ryzom/client/src/client_sheets/item_sheet.cpp
@@ -367,11 +367,6 @@ void CItemSheet::build(const NLGEORGES::UFormElm &item)
 	if (!val.empty())
 		CraftPlan = CSheetId(val);
 
-	// commands and menu label
-	TRANSLATE_VAL( Scroll.LuaCommand, "basics.Scroll.LuaCommand" );
-	TRANSLATE_VAL( Scroll.WebCommand, "basics.Scroll.WebCommand" );
-	TRANSLATE_VAL( Scroll.Label, "basics.Scroll.Label" );
-
 	// Special according to Family;
 	switch(Family)
 	{
@@ -663,9 +658,6 @@ void CItemSheet::serial(NLMISC::IStream &f)
 	// **** Serial Help Infos
 	f.serialEnum(ItemOrigin);
 
-	// item commands
-	f.serial(Scroll);
-
 	// Different Serial according to family
 	switch(Family)
 	{
@@ -705,9 +697,8 @@ void CItemSheet::serial(NLMISC::IStream &f)
 	case ITEMFAMILY::TELEPORT:
 		f.serial(Teleport);
 		break;
-	// keep for readability
 	case ITEMFAMILY::SCROLL:
-		//f.serial(Scroll);
+		f.serial(Scroll);
 		break;
 	case ITEMFAMILY::CONSUMABLE:
 		f.serial(Consumable);
diff --git a/code/ryzom/client/src/client_sheets/item_sheet.h b/code/ryzom/client/src/client_sheets/item_sheet.h
index bd79b1569..c363c9756 100644
--- a/code/ryzom/client/src/client_sheets/item_sheet.h
+++ b/code/ryzom/client/src/client_sheets/item_sheet.h
@@ -255,16 +255,10 @@ public:
 	struct CScroll
 	{
 		std::string Texture;
-		std::string LuaCommand;
-		std::string WebCommand;
-		std::string Label;
 
 		void	serial(NLMISC::IStream &f)
 		{
 			f.serial(Texture);
-			f.serial(LuaCommand);
-			f.serial(WebCommand);
-			f.serial(Label);
 		}
 	};
 

From 183ca37b1e44f3efeb03cc0b2d9e5c02d1665f58 Mon Sep 17 00:00:00 2001
From: Inky <jnk@mailoo.org>
Date: Tue, 30 Apr 2019 22:27:11 +0300
Subject: [PATCH 34/75] Backed out changeset 879f41335e4d

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_menu.h |  5 ----
 code/nel/src/gui/group_menu.cpp       | 36 ---------------------------
 2 files changed, 41 deletions(-)

diff --git a/code/nel/include/nel/gui/group_menu.h b/code/nel/include/nel/gui/group_menu.h
index ecdd8aff0..cfe91f7f9 100644
--- a/code/nel/include/nel/gui/group_menu.h
+++ b/code/nel/include/nel/gui/group_menu.h
@@ -137,9 +137,6 @@ namespace NLGUI
 		const std::string getActionHandler(uint lineIndex) const;
 		const std::string getActionHandlerParam(uint lineIndex) const;
 
-		void setActionHandler(uint lineIndex, const std::string &ah = "");
-		void setActionHandlerParam(uint lineIndex, const std::string &params = "");
-
 		void	openSubMenu (sint32 nb);
 
 		void	hideSubMenus ();
@@ -333,8 +330,6 @@ namespace NLGUI
 		const std::string getActionHandler(uint lineIndex) const;
 		const std::string getActionHandlerParam(uint lineIndex) const;
 
-		void setActionHandler(uint lineIndex, const std::string &ah = "");
-		void setActionHandlerParam(uint lineIndex, const std::string &params = "");
 
 		void addLine (const ucstring &name, const std::string &ah = "", const std::string &params = "",
 					  const std::string &id = std::string(),
diff --git a/code/nel/src/gui/group_menu.cpp b/code/nel/src/gui/group_menu.cpp
index 15a655d76..d8b3452ed 100644
--- a/code/nel/src/gui/group_menu.cpp
+++ b/code/nel/src/gui/group_menu.cpp
@@ -1663,28 +1663,6 @@ namespace NLGUI
 		return _Lines[lineIndex].AHParams;
 	}
 
-	// ------------------------------------------------------------------------------------------------
-	void CGroupSubMenu::setActionHandler(uint lineIndex, const std::string &ah)
-	{
-		if (lineIndex > _Lines.size())
-		{
-			nlwarning("Bad index");
-			return;
-		}
-		_Lines[lineIndex].AHName = ah;
-	}
-
-	// ------------------------------------------------------------------------------------------------
-	void CGroupSubMenu::setActionHandlerParam(uint lineIndex, const std::string &params)
-	{
-		if (lineIndex > _Lines.size())
-		{
-			nlwarning("Bad index");
-			return;
-		}
-		_Lines[lineIndex].AHParams = params;
-	}
-
 	// ------------------------------------------------------------------------------------------------
 	void CGroupSubMenu::setSelectable(uint lineIndex, bool selectable)
 	{
@@ -2618,20 +2596,6 @@ namespace NLGUI
 		return _RootMenu ? _RootMenu->getActionHandlerParam(lineIndex) : "";
 	}
 
-	// ------------------------------------------------------------------------------------------------
-	void CGroupMenu::setActionHandler(uint lineIndex, const std::string &ah)
-	{
-		if (_RootMenu)
-			_RootMenu->setActionHandler(lineIndex, ah);
-	}
-
-	// ------------------------------------------------------------------------------------------------
-	void CGroupMenu::setActionHandlerParam(uint lineIndex, const std::string &params)
-	{
-		if (_RootMenu)
-			_RootMenu->setActionHandlerParam(lineIndex, params);
-	}
-
 	// ------------------------------------------------------------------------------------------------
 	void CGroupMenu::setUserGroupRight(uint line, CInterfaceGroup *gr, bool ownerShip /*=true*/)
 	{

From f275bcc279e70f9e2512f678dcc9907984c88ce0 Mon Sep 17 00:00:00 2001
From: Inky <jnk@mailoo.org>
Date: Tue, 30 Apr 2019 22:27:27 +0300
Subject: [PATCH 35/75] Backed out changeset 8f53cb4efab7

--HG--
branch : develop
---
 .../src/interface_v3/action_handler_item.cpp  | 109 +-----------------
 1 file changed, 1 insertion(+), 108 deletions(-)

diff --git a/code/ryzom/client/src/interface_v3/action_handler_item.cpp b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
index 99c1147d3..d15ae130c 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_item.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_item.cpp
@@ -430,7 +430,7 @@ static	TStackMode		CurrentStackMode;
 
 
 static void validateStackItem(CDBCtrlSheet *src, CDBCtrlSheet *dest, sint32 quantity, TStackMode stackMode);
-static void checkItemCommand(const CItemSheet *itemSheet);
+
 
 //=====================================================================================================================
 /** Send a swap item msg to the server
@@ -1672,10 +1672,6 @@ class CHandlerItemCristalReload : public IActionHandler
 		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
 		if (pCS == NULL) return;
 
-		const CItemSheet *pIS = pCS->asItemSheet();
-		if (pIS && pIS->Scroll.Label.empty())
-			checkItemCommand(pIS);
-
 		sendToServerEnchantMessage((uint8)pCS->getInventoryIndex(), (uint16)pCS->getIndexInDB());
 	}
 };
@@ -1753,7 +1749,6 @@ class CHandlerItemMenuCheck : public IActionHandler
 		CViewTextMenu	*pCrisReload = dynamic_cast<CViewTextMenu*>(pMenu->getView("cris_reload"));
 		CViewTextMenu	*pTeleportUse = dynamic_cast<CViewTextMenu*>(pMenu->getView("teleport_use"));
 		CViewTextMenu	*pItemConsume = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_consume"));
-		CViewTextMenu	*pItemExecute = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_execute"));
 		CViewTextMenu	*pXpCatalyserUse = dynamic_cast<CViewTextMenu*>(pMenu->getView("xp_catalyser_use"));
 		CViewTextMenu	*pDrop = dynamic_cast<CViewTextMenu*>(pMenu->getView("drop"));
 		CViewTextMenu	*pDestroy = dynamic_cast<CViewTextMenu*>(pMenu->getView("destroy"));
@@ -1781,7 +1776,6 @@ class CHandlerItemMenuCheck : public IActionHandler
 		if(pCrisReload)	pCrisReload->setActive(false);
 		if(pTeleportUse) pTeleportUse->setActive(false);
 		if(pItemConsume) pItemConsume->setActive(false);
-		if(pItemExecute) pItemExecute->setActive(false);
 		if(pXpCatalyserUse) pXpCatalyserUse->setActive(false);
 		if(pItemTextDisplay) pItemTextDisplay->setActive(false);
 		if(pItemTextEdition) pItemTextEdition->setActive(false);
@@ -1856,61 +1850,6 @@ class CHandlerItemMenuCheck : public IActionHandler
 			{
 				pItemInfos->setActive(true);
 			}
-			// item has a label?
-			if (!pIS->Scroll.Label.empty())
-			{
-				CGroupMenu *menu = dynamic_cast<CGroupMenu *>(
-					CWidgetManager::getInstance()->getElementFromId("ui:interface:item_menu_in_bag")
-				);
-				// add the label to default menu
-				if (!pIS->Scroll.LuaCommand.empty() || !pIS->Scroll.WebCommand.empty())
-					menu->setActionHandler(4, menu->getActionHandler(4));
-				else
-				{
-					// replace default menu and redirect action handler
-					if (pCrisEnchant && pCrisEnchant->getActive())
-					{
-						pCrisEnchant->setActive(false);
-						menu->setActionHandler(4, menu->getActionHandler(0));
-					}
-					if (pCrisReload && pCrisReload->getActive())
-					{
-						pCrisReload->setActive(false);
-						menu->setActionHandler(4, menu->getActionHandler(1));
-					}
-					if (pTeleportUse && pTeleportUse->getActive())
-					{
-						pTeleportUse->setActive(false);
-						menu->setActionHandler(4, menu->getActionHandler(2));
-					}
-					if (pItemConsume && pItemConsume->getActive())
-					{
-						pItemConsume->setActive(false);
-						menu->setActionHandler(4, menu->getActionHandler(3));
-					}
-					if (pXpCatalyserUse && pXpCatalyserUse->getActive())
-					{
-						pXpCatalyserUse->setActive(false);
-						menu->setActionHandler(4, menu->getActionHandler(5));
-					}
-					if (pItemTextDisplay && pItemTextDisplay->getActive())
-					{
-						pItemTextDisplay->setActive(false);
-						menu->setActionHandler(4, menu->getActionHandler(6));
-						menu->setActionHandlerParam(4, menu->getActionHandlerParam(6));
-					}
-				}
-				if (!bIsLockedByOwner)
-				{
-					if (pCS->getInventoryIndex() == INVENTORIES::bag)
-						pItemExecute->setActive(true);
-					// enchant and reload can be used from anywhere
-					if (pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL || pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE)
-						pItemExecute->setActive(true);
-
-					pItemExecute->setText(CI18N::get(pIS->Scroll.Label));
-				}
-			}
 		}
 
 		CInventoryManager	&invMngr= getInventory();
@@ -2041,7 +1980,6 @@ class CHandlerItemMenuCheck : public IActionHandler
 			if(pCrisReload)		pCrisReload->setGrayed(true);
 			if(pTeleportUse)	pTeleportUse->setGrayed(true);
 			if(pItemConsume)	pItemConsume->setGrayed(true);
-			if(pItemExecute)	pItemExecute->setGrayed(true);
 			if(pXpCatalyserUse)	pXpCatalyserUse->setGrayed(true);
 			if(pDrop)			pDrop->setGrayed(true);
 			if(pDestroy)		pDestroy->setGrayed(true);
@@ -2061,7 +1999,6 @@ class CHandlerItemMenuCheck : public IActionHandler
 			if(pCrisReload)		pCrisReload->setGrayed(false);
 			if(pTeleportUse)	pTeleportUse->setGrayed(false);
 			if(pItemConsume)	pItemConsume->setGrayed(false);
-			if(pItemExecute)	pItemExecute->setGrayed(false);
 			if(pXpCatalyserUse)	pXpCatalyserUse->setGrayed(false);
 			if(pDrop)			pDrop->setGrayed(false);
 			if(pDestroy)		pDestroy->setGrayed(false);
@@ -2242,24 +2179,6 @@ static void sendMsgStopUseXpCat( bool isRingCatalyser )
 	}
 }
 
-// ***************************************************************************
-static void checkItemCommand(const CItemSheet *itemSheet)
-{
-	if (itemSheet)
-	{
-		if (!itemSheet->Scroll.LuaCommand.empty())
-			CLuaManager::getInstance().executeLuaScript(itemSheet->Scroll.LuaCommand);
-		// webig
-		if (!itemSheet->Scroll.WebCommand.empty())
-		{
-			CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(
-				CWidgetManager::getInstance()->getElementFromId("ui:interface:web_transactions:content:html")
-			);
-			if (pGH) pGH->browse(itemSheet->Scroll.WebCommand.c_str());
-		}
-	}
-	return;
-}
 
 // ***************************************************************************
 class CHandlerTeleportUse : public IActionHandler
@@ -2288,8 +2207,6 @@ class CHandlerTeleportUse : public IActionHandler
 					LoadingBackground = TeleportKaravanBackground;
 				break;
 			}
-			if (pIS->Scroll.Label.empty())
-				checkItemCommand(pIS);
 		}
 	}
 };
@@ -2304,28 +2221,12 @@ class CHandlerItemConsume : public IActionHandler
 		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
 		if (pCS == NULL) return;
 
-		const CItemSheet *pIS = pCS->asItemSheet();
-		if (pIS && pIS->Scroll.Label.empty())
-			checkItemCommand(pIS);
-
 		// use the item
 		sendMsgUseItem(uint16(pCS->getIndexInDB()));
 	}
 };
 REGISTER_ACTION_HANDLER( CHandlerItemConsume, "item_consume" );
 
-// ***************************************************************************
-class CHandlerItemExecute : public IActionHandler
-{
-	void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
-	{
-		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
-		if (pCS)
-			checkItemCommand(pCS->asItemSheet());
-		return;
-	}
-};
-REGISTER_ACTION_HANDLER( CHandlerItemExecute, "item_execute" );
 
 // ***************************************************************************
 class CHandlerValidateItemTextEdition : public IActionHandler
@@ -2349,10 +2250,6 @@ class CHandlerItemTextDisplay : public IActionHandler
 		if (pCSItem == NULL || windowName.empty()) 
 			return;
 
-		const CItemSheet *pIS = pCSItem->asItemSheet();
-		if (pIS && pIS->Scroll.Label.empty())
-			checkItemCommand(pIS);
-
 		CInterfaceItemEdition::getInstance()->setCurrWindow(pCSItem, windowName, false);
 	}
 };
@@ -2394,10 +2291,6 @@ class CHandlerXpCatalyserUse : public IActionHandler
 		CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
 		if (pCS == NULL) return;
 
-		const CItemSheet *pIS = pCS->asItemSheet();
-		if (pIS && pIS->Scroll.Label.empty())
-			checkItemCommand(pIS);
-
 		// use the item
 		sendMsgUseItem(uint16(pCS->getIndexInDB()));
 	}

From cbe4bf33d66d7512a22fa69ce946ff11c39b3819 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Tue, 30 Apr 2019 22:52:38 +0300
Subject: [PATCH 36/75] Changed: Use table width used min-width and allow table
 cells to properly fit

--HG--
branch : develop
---
 code/nel/src/gui/group_table.cpp | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp
index b10114a18..45c3b7e1e 100644
--- a/code/nel/src/gui/group_table.cpp
+++ b/code/nel/src/gui/group_table.cpp
@@ -843,6 +843,19 @@ namespace NLGUI
 					ratio -= _Columns[i].TableRatio;
 				}
 
+				// force table width to fit all columns
+				// if width is set, then use column min width
+				if (ForceWidthMin > 0)
+					tableWidthMax = std::min(_LastParentW - borderWidth, std::max(tableWidthMax, tableWidth));
+				else
+					tableWidthMax = std::min(_LastParentW - borderWidth, std::max(tableWidthMax, tableMaxContentWidth));
+
+				if (tableWidthMax < 0)
+					tableWidthMax = 0;
+
+				if (tableWidthMax < tableWidthMin)
+					std::swap(tableWidthMin, tableWidthMax);
+
 				// Eval table size with all percent cells resized
 				sint32 tableWidthSizeAfterPercent = tableWidth;
 				for (i=0; i<_Columns.size(); i++)

From 536937359197a70218df0069cfd50dbf4a06f8df Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Tue, 30 Apr 2019 22:52:38 +0300
Subject: [PATCH 37/75] Changed: Increase default max curl connections to 5

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_html.h | 2 +-
 code/ryzom/client/src/client_cfg.cpp  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index c4a5c8a34..dedf3a0bf 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -69,7 +69,7 @@ namespace NLGUI
 			/// Maximum concurrent MultiCurl connections per CGroupHTML instance
 			sint32 curlMaxConnections;
 
-			SWebOptions(): curlMaxConnections(2)
+			SWebOptions(): curlMaxConnections(5)
 			{
 			}
 		};
diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp
index 2e7531d07..52e08463d 100644
--- a/code/ryzom/client/src/client_cfg.cpp
+++ b/code/ryzom/client/src/client_cfg.cpp
@@ -436,7 +436,7 @@ CClientConfig::CClientConfig()
 	WebIgTrustedDomains.push_back(WebIgMainDomain);
 	WebIgNotifInterval = 10; // time in minutes
 
-	CurlMaxConnections = 2;
+	CurlMaxConnections = 5;
 	CurlCABundle.clear();
 
 	RingReleaseNotePath = "http://" + WebIgMainDomain + "/releasenotes_ring/index.php";

From 2e84381bfaf24296438ff4330da0f9d38710b4b6 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Tue, 30 Apr 2019 22:52:38 +0300
Subject: [PATCH 38/75] Changed: Do not show spinning cursor for image
 downloads

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 24baac399..af2b6fd0b 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -2519,9 +2519,10 @@ namespace NLGUI
 
 	bool CGroupHTML::isBrowsing()
 	{
+		// do not show spinning cursor for image downloads (!Curls.empty())
 		return _BrowseNextTime || _PostNextTime || _RenderNextTime ||
 			_Browsing || _WaitingForStylesheet ||
-			_CurlWWW ||  !Curls.empty();
+			_CurlWWW;
 	}
 
 	// ***************************************************************************

From 4fcd71d7ba97e97acec0a01f7794817763f0b849 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Tue, 30 Apr 2019 22:52:38 +0300
Subject: [PATCH 39/75] Changed: Use lower connection timeout for css/img/data
 downloads

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_html.h | 3 ++-
 code/nel/src/gui/group_html.cpp       | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index dedf3a0bf..e5a2670a4 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -746,7 +746,7 @@ namespace NLGUI
 		{
 		public:
 			CDataDownload(const std::string &u, const std::string &d, TDataType t, CViewBase *i, const std::string &s, const std::string &m, const CStyleParams &style = CStyleParams(), const TImageType imagetype = NormalImage)
-				: data(NULL), fp(NULL), url(u), dest(d), type(t), luaScript(s), md5sum(m), redirects(0)
+				: data(NULL), fp(NULL), url(u), dest(d), type(t), luaScript(s), md5sum(m), redirects(0), ConnectionTimeout(60)
 			{
 				if (t == ImgType) imgs.push_back(CDataImageDownload(i, style, imagetype));
 			}
@@ -762,6 +762,7 @@ namespace NLGUI
 			uint32 redirects;
 			FILE *fp;
 			std::vector<CDataImageDownload> imgs;
+			uint32 ConnectionTimeout;
 		};
 
 		std::list<CDataDownload> Curls;
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index af2b6fd0b..90fd48c5c 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -546,6 +546,9 @@ namespace NLGUI
 		download.data = new CCurlWWWData(curl, download.url);
 		download.fp = fp;
 
+		// initial connection timeout, curl default is 300sec
+		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, download.ConnectionTimeout);
+
 		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
 		curl_easy_setopt(curl, CURLOPT_URL, download.url.c_str());
 

From ff3b4cfabd6ea4ea4ec9e90e71e6e9e124893a2c Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Tue, 30 Apr 2019 22:52:38 +0300
Subject: [PATCH 40/75] Changed: Change long if blocks to early exits

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp | 747 ++++++++++++++++----------------
 1 file changed, 379 insertions(+), 368 deletions(-)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 90fd48c5c..218ff06cf 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -5539,65 +5539,67 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::htmlIMG(const CHtmlElement &elm)
 	{
-		// Get the string name
-		if (elm.hasNonEmptyAttribute("src"))
+		std::string src = trim(elm.getAttribute("src"));
+		if (src.empty())
 		{
-			float tmpf;
-			std::string id = elm.getAttribute("id");
-			std::string src = elm.getAttribute("src");
+			// no 'src' attribute, or empty
+			return;
+		}
 
-			if (elm.hasNonEmptyAttribute("width"))
-				getPercentage(_Style.Current.Width, tmpf, elm.getAttribute("width").c_str());
-			if (elm.hasNonEmptyAttribute("height"))
-				getPercentage(_Style.Current.Height, tmpf, elm.getAttribute("height").c_str());
+		float tmpf;
+		std::string id = elm.getAttribute("id");
 
-			// Get the global color name
-			if (elm.hasAttribute("global_color"))
-				_Style.Current.GlobalColor = true;
+		if (elm.hasNonEmptyAttribute("width"))
+			getPercentage(_Style.Current.Width, tmpf, elm.getAttribute("width").c_str());
+		if (elm.hasNonEmptyAttribute("height"))
+			getPercentage(_Style.Current.Height, tmpf, elm.getAttribute("height").c_str());
 
-			// Tooltip
-			// keep "alt" attribute for backward compatibility
-			std::string strtooltip = elm.getAttribute("alt");
-			// tooltip
-			if (elm.hasNonEmptyAttribute("title"))
-				strtooltip = elm.getAttribute("title");
+		// Get the global color name
+		if (elm.hasAttribute("global_color"))
+			_Style.Current.GlobalColor = true;
 
-			const char *tooltip = NULL;
-			// note: uses pointer to string data
-			if (!strtooltip.empty())
-				tooltip = strtooltip.c_str();
+		// Tooltip
+		// keep "alt" attribute for backward compatibility
+		std::string strtooltip = elm.getAttribute("alt");
+		// tooltip
+		if (elm.hasNonEmptyAttribute("title"))
+			strtooltip = elm.getAttribute("title");
 
-			// Mouse over image
-			string overSrc = elm.getAttribute("data-over-src");
+		const char *tooltip = NULL;
+		// note: uses pointer to string data
+		if (!strtooltip.empty())
+			tooltip = strtooltip.c_str();
 
-			if (getA() && getParent () && getParent ()->getParent())
+		// Mouse over image
+		string overSrc = elm.getAttribute("data-over-src");
+
+		if (getA() && getParent () && getParent ()->getParent())
+		{
+			string params = "name=" + getId() + "|url=" + getLink ();
+			addButton(CCtrlButton::PushButton, id, src, src, overSrc, "browse", params.c_str(), tooltip, _Style.Current);
+		}
+		else
+		if (tooltip || !overSrc.empty())
+		{
+			addButton(CCtrlButton::PushButton, id, src, src, overSrc, "", "", tooltip, _Style.Current);
+		}
+		else
+		{
+			// Get the option to reload (class==reload)
+			bool reloadImg = false;
+
+			if (elm.hasNonEmptyAttribute("style"))
 			{
-				string params = "name=" + getId() + "|url=" + getLink ();
-				addButton(CCtrlButton::PushButton, id, src, src, overSrc, "browse", params.c_str(), tooltip, _Style.Current);
-			}
-			else
-			if (tooltip || !overSrc.empty())
-			{
-				addButton(CCtrlButton::PushButton, id, src, src, overSrc, "", "", tooltip, _Style.Current);
-			}
-			else
-			{
-				// Get the option to reload (class==reload)
-				bool reloadImg = false;
+				string styleString = elm.getAttribute("style");
+				TStyle styles = parseStyle(styleString);
+				TStyle::iterator	it;
 
-				if (elm.hasNonEmptyAttribute("style"))
-				{
-					string styleString = elm.getAttribute("style");
-					TStyle styles = parseStyle(styleString);
-					TStyle::iterator	it;
-
-					it = styles.find("reload");
-					if (it != styles.end() && (*it).second == "1")
-						reloadImg = true;
-				}
-
-				addImage(id, elm.getAttribute("src"), reloadImg, _Style.Current);
+				it = styles.find("reload");
+				if (it != styles.end() && (*it).second == "1")
+					reloadImg = true;
 			}
+
+			addImage(id, elm.getAttribute("src"), reloadImg, _Style.Current);
 		}
 	}
 
@@ -5619,220 +5621,223 @@ namespace NLGUI
 		// Widget minimal width
 		string minWidth = elm.getAttribute("z_input_width");
 
-		// Get the type
-		if (elm.hasNonEmptyAttribute("type"))
+		// <input type="...">
+		std::string type = trim(elm.getAttribute("type"));
+		if (type.empty())
 		{
-			// Global color flag
-			if (elm.hasAttribute("global_color"))
-				_Style.Current.GlobalColor = true;
+			// no 'type' attribute, or empty
+			return;
+		}
+	
+		// Global color flag
+		if (elm.hasAttribute("global_color"))
+			_Style.Current.GlobalColor = true;
 
-			// Tooltip
-			std::string strtooltip = elm.getAttribute("alt");
-			const char *tooltip = NULL;
-			// note: uses pointer to strtooltip data
-			if (!strtooltip.empty())
-				tooltip = strtooltip.c_str();
+		// Tooltip
+		std::string strtooltip = elm.getAttribute("alt");
+		const char *tooltip = NULL;
+		// note: uses pointer to strtooltip data
+		if (!strtooltip.empty())
+			tooltip = strtooltip.c_str();
 
-			string type = toLower(elm.getAttribute("type"));
-			if (type == "image")
+		if (type == "image")
+		{
+			// The submit button
+			string name = elm.getAttribute("name");
+			string normal = elm.getAttribute("src");
+			string pushed;
+			string over;
+
+			// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
+			string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=image";
+
+			// Add the ctrl button
+			addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
+				"html_submit_form", param.c_str(), tooltip, _Style.Current);
+		}
+		else if (type == "button" || type == "submit")
+		{
+			// The submit button
+			string name = elm.getAttribute("name");
+			string normal = elm.getAttribute("src");
+			string text = elm.getAttribute("value");
+			string pushed;
+			string over;
+
+			string buttonTemplate(!templateName.empty() ? templateName : DefaultButtonGroup );
+
+			// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
+			string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=submit";
+			if (!text.empty())
 			{
-				// The submit button
-				string name = elm.getAttribute("name");
-				string normal = elm.getAttribute("src");
-				string pushed;
-				string over;
-
-				// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
-				string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=image";
-
-				// Add the ctrl button
-				addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
-					"html_submit_form", param.c_str(), tooltip, _Style.Current);
+				// escape AH param separator
+				string tmp = text;
+				while(NLMISC::strFindReplace(tmp, "|", "&#124;"))
+					;
+				param = param + "|submit_button_value=" + tmp;
 			}
-			else if (type == "button" || type == "submit")
+
+			// Add the ctrl button
+			if (!_Paragraph)
 			{
-				// The submit button
-				string name = elm.getAttribute("name");
-				string normal = elm.getAttribute("src");
-				string text = elm.getAttribute("value");
-				string pushed;
-				string over;
+				newParagraph (0);
+				paragraphChange ();
+			}
 
-				string buttonTemplate(!templateName.empty() ? templateName : DefaultButtonGroup );
-
-				// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
-				string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=submit";
-				if (!text.empty())
-				{
-					// escape AH param separator
-					string tmp = text;
-					while(NLMISC::strFindReplace(tmp, "|", "&#124;"))
-						;
-					param = param + "|submit_button_value=" + tmp;
-				}
+			typedef pair<string, string> TTmplParam;
+			vector<TTmplParam> tmplParams;
+			tmplParams.push_back(TTmplParam("id", name));
+			tmplParams.push_back(TTmplParam("onclick", "html_submit_form"));
+			tmplParams.push_back(TTmplParam("onclick_param", param));
+			//tmplParams.push_back(TTmplParam("text", text));
+			tmplParams.push_back(TTmplParam("active", "true"));
+			if (!minWidth.empty())
+				tmplParams.push_back(TTmplParam("wmin", minWidth));
+			CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
+			if (buttonGroup)
+			{
 
 				// Add the ctrl button
-				if (!_Paragraph)
+				CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button"));
+				if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
+				if (ctrlButton)
 				{
-					newParagraph (0);
-					paragraphChange ();
-				}
+					ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
 
-				typedef pair<string, string> TTmplParam;
-				vector<TTmplParam> tmplParams;
-				tmplParams.push_back(TTmplParam("id", name));
-				tmplParams.push_back(TTmplParam("onclick", "html_submit_form"));
-				tmplParams.push_back(TTmplParam("onclick_param", param));
-				//tmplParams.push_back(TTmplParam("text", text));
-				tmplParams.push_back(TTmplParam("active", "true"));
-				if (!minWidth.empty())
-					tmplParams.push_back(TTmplParam("wmin", minWidth));
-				CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
-				if (buttonGroup)
-				{
-
-					// Add the ctrl button
-					CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button"));
-					if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
-					if (ctrlButton)
+					// Translate the tooltip
+					if (tooltip)
 					{
-						ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
-
-						// Translate the tooltip
-						if (tooltip)
+						if (CI18N::hasTranslation(tooltip))
 						{
-							if (CI18N::hasTranslation(tooltip))
-							{
-								ctrlButton->setDefaultContextHelp(CI18N::get(tooltip));
-							}
-							else
-							{
-								ctrlButton->setDefaultContextHelp(ucstring(tooltip));
-							}
+							ctrlButton->setDefaultContextHelp(CI18N::get(tooltip));
+						}
+						else
+						{
+							ctrlButton->setDefaultContextHelp(ucstring(tooltip));
 						}
-
-						ctrlButton->setText(ucstring::makeFromUtf8(text));
-
-						setTextButtonStyle(ctrlButton, _Style.Current);
 					}
-					getParagraph()->addChild (buttonGroup);
-					paragraphChange ();
+
+					ctrlButton->setText(ucstring::makeFromUtf8(text));
+
+					setTextButtonStyle(ctrlButton, _Style.Current);
 				}
+				getParagraph()->addChild (buttonGroup);
+				paragraphChange ();
 			}
-			else if (type == "text")
+		}
+		else if (type == "text")
+		{
+			// Get the string name
+			string name = elm.getAttribute("name");
+			ucstring ucValue;
+			ucValue.fromUtf8(elm.getAttribute("value"));
+
+			uint size = 120;
+			uint maxlength = 1024;
+			if (elm.hasNonEmptyAttribute("size"))
+				fromString(elm.getAttribute("size"), size);
+			if (elm.hasNonEmptyAttribute("maxlength"))
+				fromString(elm.getAttribute("maxlength"), maxlength);
+
+			string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup);
+			// Add the editbox
+			CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue, maxlength);
+			if (textArea)
 			{
-				// Get the string name
+				// Add the text area to the form
+				CGroupHTML::CForm::CEntry entry;
+				entry.Name = name;
+				entry.TextArea = textArea;
+				_Forms.back().Entries.push_back (entry);
+			}
+		}
+		else if (type == "checkbox" || type == "radio")
+		{
+			renderPseudoElement(":before", elm);
+
+			CCtrlButton::EType btnType;
+			string name = elm.getAttribute("name");
+			string normal = elm.getAttribute("src");
+			string pushed;
+			string over;
+			ucstring ucValue = ucstring("on");
+			bool checked = elm.hasAttribute("checked");
+
+			// TODO: unknown if empty attribute should override or not
+			if (elm.hasNonEmptyAttribute("value"))
+				ucValue.fromUtf8(elm.getAttribute("value"));
+
+			if (type == "radio")
+			{
+				btnType = CCtrlButton::RadioButton;
+				normal = DefaultRadioButtonBitmapNormal;
+				pushed = DefaultRadioButtonBitmapPushed;
+				over = DefaultRadioButtonBitmapOver;
+			}
+			else
+			{
+				btnType = CCtrlButton::ToggleButton;
+				normal = DefaultCheckBoxBitmapNormal;
+				pushed = DefaultCheckBoxBitmapPushed;
+				over = DefaultCheckBoxBitmapOver;
+			}
+
+			// Add the ctrl button
+			CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style.Current);
+			if (checkbox)
+			{
+				if (btnType == CCtrlButton::RadioButton)
+				{
+					// override with 'id' because radio buttons share same name
+					if (!id.empty())
+						checkbox->setId(id);
+
+					// group together buttons with same name
+					CForm &form = _Forms.back();
+					bool notfound = true;
+					for (uint i=0; i<form.Entries.size(); i++)
+					{
+						if (form.Entries[i].Name == name && form.Entries[i].Checkbox->getType() == CCtrlButton::RadioButton)
+						{
+							checkbox->initRBRefFromRadioButton(form.Entries[i].Checkbox);
+							notfound = false;
+							break;
+						}
+					}
+					if (notfound)
+					{
+						// this will start a new group (initRBRef() would take first button in group container otherwise)
+						checkbox->initRBRefFromRadioButton(checkbox);
+					}
+				}
+
+				checkbox->setPushed (checked);
+
+				// Add the button to the form
+				CGroupHTML::CForm::CEntry entry;
+				entry.Name = name;
+				entry.Value = decodeHTMLEntities(ucValue);
+				entry.Checkbox = checkbox;
+				_Forms.back().Entries.push_back (entry);
+			}
+			renderPseudoElement(":after", elm);
+		}
+		else if (type == "hidden")
+		{
+			if (elm.hasNonEmptyAttribute("name"))
+			{
+				// Get the name
 				string name = elm.getAttribute("name");
+
+				// Get the value
 				ucstring ucValue;
 				ucValue.fromUtf8(elm.getAttribute("value"));
 
-				uint size = 120;
-				uint maxlength = 1024;
-				if (elm.hasNonEmptyAttribute("size"))
-					fromString(elm.getAttribute("size"), size);
-				if (elm.hasNonEmptyAttribute("maxlength"))
-					fromString(elm.getAttribute("maxlength"), maxlength);
-
-				string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup);
-				// Add the editbox
-				CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue, maxlength);
-				if (textArea)
-				{
-					// Add the text area to the form
-					CGroupHTML::CForm::CEntry entry;
-					entry.Name = name;
-					entry.TextArea = textArea;
-					_Forms.back().Entries.push_back (entry);
-				}
-			}
-			else if (type == "checkbox" || type == "radio")
-			{
-				renderPseudoElement(":before", elm);
-
-				CCtrlButton::EType btnType;
-				string name = elm.getAttribute("name");
-				string normal = elm.getAttribute("src");
-				string pushed;
-				string over;
-				ucstring ucValue = ucstring("on");
-				bool checked = elm.hasAttribute("checked");
-
-				// TODO: unknown if empty attribute should override or not
-				if (elm.hasNonEmptyAttribute("value"))
-					ucValue.fromUtf8(elm.getAttribute("value"));
-
-				if (type == "radio")
-				{
-					btnType = CCtrlButton::RadioButton;
-					normal = DefaultRadioButtonBitmapNormal;
-					pushed = DefaultRadioButtonBitmapPushed;
-					over = DefaultRadioButtonBitmapOver;
-				}
-				else
-				{
-					btnType = CCtrlButton::ToggleButton;
-					normal = DefaultCheckBoxBitmapNormal;
-					pushed = DefaultCheckBoxBitmapPushed;
-					over = DefaultCheckBoxBitmapOver;
-				}
-
-				// Add the ctrl button
-				CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style.Current);
-				if (checkbox)
-				{
-					if (btnType == CCtrlButton::RadioButton)
-					{
-						// override with 'id' because radio buttons share same name
-						if (!id.empty())
-							checkbox->setId(id);
-
-						// group together buttons with same name
-						CForm &form = _Forms.back();
-						bool notfound = true;
-						for (uint i=0; i<form.Entries.size(); i++)
-						{
-							if (form.Entries[i].Name == name && form.Entries[i].Checkbox->getType() == CCtrlButton::RadioButton)
-							{
-								checkbox->initRBRefFromRadioButton(form.Entries[i].Checkbox);
-								notfound = false;
-								break;
-							}
-						}
-						if (notfound)
-						{
-							// this will start a new group (initRBRef() would take first button in group container otherwise)
-							checkbox->initRBRefFromRadioButton(checkbox);
-						}
-					}
-
-					checkbox->setPushed (checked);
-
-					// Add the button to the form
-					CGroupHTML::CForm::CEntry entry;
-					entry.Name = name;
-					entry.Value = decodeHTMLEntities(ucValue);
-					entry.Checkbox = checkbox;
-					_Forms.back().Entries.push_back (entry);
-				}
-				renderPseudoElement(":after", elm);
-			}
-			else if (type == "hidden")
-			{
-				if (elm.hasNonEmptyAttribute("name"))
-				{
-					// Get the name
-					string name = elm.getAttribute("name");
-
-					// Get the value
-					ucstring ucValue;
-					ucValue.fromUtf8(elm.getAttribute("value"));
-
-					// Add an entry
-					CGroupHTML::CForm::CEntry entry;
-					entry.Name = name;
-					entry.Value = decodeHTMLEntities(ucValue);
-					_Forms.back().Entries.push_back (entry);
-				}
+				// Add an entry
+				CGroupHTML::CForm::CEntry entry;
+				entry.Name = name;
+				entry.Value = decodeHTMLEntities(ucValue);
+				_Forms.back().Entries.push_back (entry);
 			}
 		}
 	}
@@ -5908,31 +5913,33 @@ namespace NLGUI
 
 		std::string httpEquiv = elm.getAttribute("http-equiv");
 		std::string httpContent = elm.getAttribute("content");
-		if (!httpEquiv.empty() && !httpContent.empty())
+		if (httpEquiv.empty() || httpContent.empty())
 		{
-			// only first http-equiv="refresh" should be handled
-			if (_RefreshUrl.empty() && httpEquiv == "refresh")
+			return;
+		}
+
+		// only first http-equiv="refresh" should be handled
+		if (_RefreshUrl.empty() && httpEquiv == "refresh")
+		{
+			const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
+			double timeSec = times.thisFrameMs / 1000.0f;
+
+			string::size_type pos = httpContent.find_first_of(";");
+			if (pos == string::npos)
 			{
-				const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
-				double timeSec = times.thisFrameMs / 1000.0f;
-
-				string::size_type pos = httpContent.find_first_of(";");
-				if (pos == string::npos)
-				{
-					fromString(httpContent, _NextRefreshTime);
-					_RefreshUrl = _URL;
-				}
-				else
-				{
-					fromString(httpContent.substr(0, pos), _NextRefreshTime);
-
-					pos = toLower(httpContent).find("url=");
-					if (pos != string::npos)
-						_RefreshUrl = getAbsoluteUrl(httpContent.substr(pos + 4));
-				}
-
-				_NextRefreshTime += timeSec;
+				fromString(httpContent, _NextRefreshTime);
+				_RefreshUrl = _URL;
 			}
+			else
+			{
+				fromString(httpContent.substr(0, pos), _NextRefreshTime);
+
+				pos = toLower(httpContent).find("url=");
+				if (pos != string::npos)
+					_RefreshUrl = getAbsoluteUrl(httpContent.substr(pos + 4));
+			}
+
+			_NextRefreshTime += timeSec;
 		}
 	}
 
@@ -6298,85 +6305,91 @@ namespace NLGUI
 		}
 
 		CGroupTable *table = getTable();
-		if (table)
+		if (!table)
 		{
-			if (_Style.hasStyle("padding"))
+			// <td> appears to be outside <table>
+			return;
+		}
+
+		if (_Cells.empty())
+		{
+			// <table> not started
+			return;
+		}
+
+		if (_Style.hasStyle("padding"))
+		{
+			uint32 a;
+			// TODO: cssLength
+			if (fromString(_Style.getStyle("padding"), a))
+				table->CellPadding = a;
+		}
+
+		_Cells.back() = new CGroupCell(CViewBase::TCtorParam());
+
+		if (_Style.checkStyle("background-repeat", "1") || _Style.checkStyle("background-repeat", "repeat"))
+			_Cells.back()->setTextureTile(true);
+
+		if (_Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "cover"))
+			_Cells.back()->setTextureScale(true);
+
+		if (_Style.hasStyle("background-image"))
+		{
+			string image = _Style.getStyle("background-image");
+
+			string::size_type texExt = toLower(image).find("url(");
+			// Url image
+			if (texExt != string::npos)
 			{
-				uint32 a;
-				// TODO: cssLength
-				if (fromString(_Style.getStyle("padding"), a))
-					table->CellPadding = a;
+				// Remove url()
+				image = image.substr(4, image.size()-5);
+				addImageDownload(image, _Cells.back());
+			// Image in BNP
 			}
-
-			if (!_Cells.empty())
+			else
 			{
-				_Cells.back() = new CGroupCell(CViewBase::TCtorParam());
-
-				if (_Style.checkStyle("background-repeat", "1") || _Style.checkStyle("background-repeat", "repeat"))
-					_Cells.back()->setTextureTile(true);
-
-				if (_Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "cover"))
-					_Cells.back()->setTextureScale(true);
-
-				if (_Style.hasStyle("background-image"))
-				{
-					string image = _Style.getStyle("background-image");
-
-					string::size_type texExt = toLower(image).find("url(");
-					// Url image
-					if (texExt != string::npos)
-					{
-						// Remove url()
-						image = image.substr(4, image.size()-5);
-						addImageDownload(image, _Cells.back());
-					// Image in BNP
-					}
-					else
-					{
-						_Cells.back()->setTexture(image);
-					}
-				}
-
-				if (elm.hasNonEmptyAttribute("colspan"))
-					fromString(elm.getAttribute("colspan"), _Cells.back()->ColSpan);
-				if (elm.hasNonEmptyAttribute("rowspan"))
-					fromString(elm.getAttribute("rowspan"), _Cells.back()->RowSpan);
-
-				_Cells.back()->BgColor = _CellParams.back().BgColor;
-				_Cells.back()->Align = _CellParams.back().Align;
-				_Cells.back()->VAlign = _CellParams.back().VAlign;
-				_Cells.back()->LeftMargin = _CellParams.back().LeftMargin;
-				_Cells.back()->NoWrap = _CellParams.back().NoWrap;
-				_Cells.back()->ColSpan = std::max(1, _Cells.back()->ColSpan);
-				_Cells.back()->RowSpan = std::max(1, _Cells.back()->RowSpan);
-
-				float temp;
-				if (_Style.hasStyle("width"))
-					getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, _Style.getStyle("width").c_str());
-				else if (elm.hasNonEmptyAttribute("width"))
-					getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, elm.getAttribute("width").c_str());
-				
-				if (_Style.hasStyle("height"))
-					getPercentage (_Cells.back()->Height, temp, _Style.getStyle("height").c_str());
-				else if (elm.hasNonEmptyAttribute("height"))
-					getPercentage (_Cells.back()->Height, temp, elm.getAttribute("height").c_str());
-
-				_Cells.back()->NewLine = getTR();
-				table->addChild (_Cells.back());
-
-				// reusing indent pushed by table
-				_Indent.back() = 0;
-
-				newParagraph(TDBeginSpace);
-				// indent is already 0, getParagraph()->setMarginLeft(0); // maybe setIndent(0) if LI is using one
-
-				// Reset TR flag
-				if (!_TR.empty())
-					_TR.back() = false;
-
-				renderPseudoElement(":before", elm);
+				_Cells.back()->setTexture(image);
 			}
 		}
+
+		if (elm.hasNonEmptyAttribute("colspan"))
+			fromString(elm.getAttribute("colspan"), _Cells.back()->ColSpan);
+		if (elm.hasNonEmptyAttribute("rowspan"))
+			fromString(elm.getAttribute("rowspan"), _Cells.back()->RowSpan);
+
+		_Cells.back()->BgColor = _CellParams.back().BgColor;
+		_Cells.back()->Align = _CellParams.back().Align;
+		_Cells.back()->VAlign = _CellParams.back().VAlign;
+		_Cells.back()->LeftMargin = _CellParams.back().LeftMargin;
+		_Cells.back()->NoWrap = _CellParams.back().NoWrap;
+		_Cells.back()->ColSpan = std::max(1, _Cells.back()->ColSpan);
+		_Cells.back()->RowSpan = std::max(1, _Cells.back()->RowSpan);
+
+		float temp;
+		if (_Style.hasStyle("width"))
+			getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, _Style.getStyle("width").c_str());
+		else if (elm.hasNonEmptyAttribute("width"))
+			getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, elm.getAttribute("width").c_str());
+		
+		if (_Style.hasStyle("height"))
+			getPercentage (_Cells.back()->Height, temp, _Style.getStyle("height").c_str());
+		else if (elm.hasNonEmptyAttribute("height"))
+			getPercentage (_Cells.back()->Height, temp, elm.getAttribute("height").c_str());
+
+		_Cells.back()->NewLine = getTR();
+		table->addChild (_Cells.back());
+
+		// reusing indent pushed by table
+		_Indent.back() = 0;
+
+		newParagraph(TDBeginSpace);
+		// indent is already 0, getParagraph()->setMarginLeft(0); // maybe setIndent(0) if LI is using one
+
+		// Reset TR flag
+		if (!_TR.empty())
+			_TR.back() = false;
+
+		renderPseudoElement(":before", elm);
 	}
 
 	void CGroupHTML::htmlTDend(const CHtmlElement &elm)
@@ -6391,43 +6404,38 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::htmlTEXTAREA(const CHtmlElement &elm)
 	{
+		if (_Forms.empty())
+			return;
+
+		// read general property
+		string templateName;
+
+		// Widget template name
+		if (elm.hasNonEmptyAttribute("z_input_tmpl"))
+			templateName = elm.getAttribute("z_input_tmpl");
+
+		// Get the string name
+		_TextAreaName.clear();
+		_TextAreaRow = 1;
+		_TextAreaCols = 10;
+		_TextAreaContent.clear();
+		_TextAreaMaxLength = 1024;
+		if (elm.hasNonEmptyAttribute("name"))
+			_TextAreaName = elm.getAttribute("name");
+		if (elm.hasNonEmptyAttribute("rows"))
+			fromString(elm.getAttribute("rows"), _TextAreaRow);
+		if (elm.hasNonEmptyAttribute("cols"))
+			fromString(elm.getAttribute("cols"), _TextAreaCols);
+		if (elm.hasNonEmptyAttribute("maxlength"))
+			fromString(elm.getAttribute("maxlength"), _TextAreaMaxLength);
+
+		_TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup;
+		_TextArea = true;
 		_PRE.push_back(true);
-
-		// Got one form ?
-		if (!(_Forms.empty()))
-		{
-			// read general property
-			string templateName;
-
-			// Widget template name
-			if (elm.hasNonEmptyAttribute("z_input_tmpl"))
-				templateName = elm.getAttribute("z_input_tmpl");
-
-			// Get the string name
-			_TextAreaName.clear();
-			_TextAreaRow = 1;
-			_TextAreaCols = 10;
-			_TextAreaContent.clear();
-			_TextAreaMaxLength = 1024;
-			if (elm.hasNonEmptyAttribute("name"))
-				_TextAreaName = elm.getAttribute("name");
-			if (elm.hasNonEmptyAttribute("rows"))
-				fromString(elm.getAttribute("rows"), _TextAreaRow);
-			if (elm.hasNonEmptyAttribute("cols"))
-				fromString(elm.getAttribute("cols"), _TextAreaCols);
-			if (elm.hasNonEmptyAttribute("maxlength"))
-				fromString(elm.getAttribute("maxlength"), _TextAreaMaxLength);
-
-			_TextAreaTemplate = !templateName.empty() ? templateName : DefaultFormTextAreaGroup;
-			_TextArea = true;
-		}
 	}
 
 	void CGroupHTML::htmlTEXTAREAend(const CHtmlElement &elm)
 	{
-		_TextArea = false;
-		popIfNotEmpty (_PRE);
-
 		if (_Forms.empty())
 			return;
 
@@ -6440,6 +6448,9 @@ namespace NLGUI
 			entry.TextArea = textArea;
 			_Forms.back().Entries.push_back (entry);
 		}
+
+		_TextArea = false;
+		popIfNotEmpty (_PRE);
 	}
 
 	// ***************************************************************************

From 39c313aeb6798f639b3c1a77a5975cf0fa0f3f93 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 04:57:58 +0800
Subject: [PATCH 41/75] Add editor formatting settings

---
 code/.clang-format | 24 ++++++++++++++++++++++++
 code/.editorconfig | 23 +++++++++++++++++++++++
 2 files changed, 47 insertions(+)
 create mode 100644 code/.clang-format
 create mode 100644 code/.editorconfig

diff --git a/code/.clang-format b/code/.clang-format
new file mode 100644
index 000000000..90f4ab553
--- /dev/null
+++ b/code/.clang-format
@@ -0,0 +1,24 @@
+---
+BasedOnStyle: WebKit
+AllowShortFunctionsOnASingleLine: All
+BraceWrapping:
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  BeforeCatch:     true
+  BeforeElse:      true
+  IndentBraces:    false
+BreakBeforeBraces: Custom
+BreakConstructorInitializersBeforeComma: 'false'
+NamespaceIndentation: None
+PointerAlignment: Right
+SortIncludes: 'false'
+TabWidth: '4'
+UseTab: ForIndentation
+
+...
diff --git a/code/.editorconfig b/code/.editorconfig
new file mode 100644
index 000000000..e4aef2c53
--- /dev/null
+++ b/code/.editorconfig
@@ -0,0 +1,23 @@
+; Top-most EditorConfig file
+root = true
+
+; 4-column tab indentation
+[*.cpp]
+indent_style = tab
+indent_size = 4
+
+[*.c]
+indent_style = tab
+indent_size = 4
+
+[*.h]
+indent_style = tab
+indent_size = 4
+
+[*.py]
+indent_style = tab
+indent_size = 4
+
+[*.config]
+indent_style = space
+indent_size = 2

From 8efe1d91c4c3371831b6e01c2b315bfd97cb76d0 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 05:01:30 +0800
Subject: [PATCH 42/75] Added: More comprehensive codepage conversion for
 tstring

---
 code/nel/include/nel/misc/common.h        |  10 +-
 code/nel/include/nel/misc/string_common.h | 151 ++++++++----
 code/nel/include/nel/misc/types_nl.h      |   6 +
 code/nel/src/misc/string_common.cpp       | 272 +++++++++++++++++++++-
 4 files changed, 381 insertions(+), 58 deletions(-)

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index 8ad0b5dcc..48468d6fd 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -303,23 +303,23 @@ inline sint nlstricmp(const std::string &lhs, const std::string &rhs) { return s
 inline sint nlstricmp(const std::string &lhs, const char *rhs) { return stricmp(lhs.c_str(),rhs); }
 inline sint nlstricmp(const char *lhs, const std::string &rhs) { return stricmp(lhs,rhs.c_str()); }
 
-// TODO: Can we prefix these with 'nl' like other methods?
+// TODO: Can we prefix these with 'nl' like other macros?
 // Macros helper to convert UTF-8 std::string and wchar_t*
-#define wideToUtf8(str) (ucstring((ucchar*)str).toUtf8())
-#define utf8ToWide(str) ((wchar_t*)ucstring::makeFromUtf8(str).c_str())
+// #define wideToUtf8(str) (ucstring((ucchar*)str).toUtf8())
+// #define utf8ToWide(str) ((wchar_t*)ucstring::makeFromUtf8(str).c_str())
 
 // Macros helper to convert UTF-8 std::string and TCHAR*
 #ifdef _UNICODE
 #define tStrToUtf8(str) (ucstring((ucchar*)(LPCWSTR)str).toUtf8())
 #define utf8ToTStr(str) ((const wchar_t *)ucstring::makeFromUtf8(str).c_str())
-#define tstring wstring
+// #define tstring wstring
 #else
 // FIXME: This is not accurate, it should be a conversion between local charset and utf8
 #define tStrToUtf8(str) (std::string((LPCSTR)str))
 inline const char *nlutf8ToTStr(const char *str) { return str; }
 inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
 #define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
-#define tstring string
+// #define tstring string
 #endif
 
 #if (NL_COMP_VC_VERSION <= 90)
diff --git a/code/nel/include/nel/misc/string_common.h b/code/nel/include/nel/misc/string_common.h
index 02cafec92..4b757b989 100644
--- a/code/nel/include/nel/misc/string_common.h
+++ b/code/nel/include/nel/misc/string_common.h
@@ -246,55 +246,7 @@ inline bool fromString(const std::string &str, double &val) { bool ret = sscanf(
 // (str[0] == '1' || (str[0] & 0xD2) == 0x50)
 //  - Kaetemi
 
-inline bool fromString(const std::string &str, bool &val)
-{
-	if (str.length() == 1)
-	{
-		const char c = str[0];
-
-		switch(c)
-		{
-			case '1':
-			case 't':
-			case 'T':
-			case 'y':
-			case 'Y':
-			val = true;
-			break;
-
-			case '0':
-			case 'f':
-			case 'F':
-			case 'n':
-			case 'N':
-			val = false;
-			break;
-
-			default:
-			val = false;
-			return false;
-		}
-	}
-	else
-	{
-		std::string strl = toLower(str);
-		if (strl == "true" || strl == "yes")
-		{
-			val = true;
-		}
-		else if (strl == "false" || strl == "no")
-		{
-			val = false;
-		}
-		else
-		{
-			val = false;
-			return false;
-		}
-	}
-
-	return true;
-}
+bool fromString(const std::string &str, bool &val);
 
 inline bool fromString(const std::string &str, std::string &val) { val = str; return true; }
 
@@ -305,6 +257,107 @@ inline bool fromString(const std::string &str, uint &val) { return sscanf(str.c_
 inline bool fromString(const std::string &str, sint &val) { return sscanf(str.c_str(), "%d", &val) == 1; }
 #endif // NL_COMP_VC6
 
+// Convert local codepage to UTF-8
+// On Windows, the local codepage is undetermined
+// On Linux, the local codepage is always UTF-8 (no-op)
+std::string mbcsToUtf8(const char *str, size_t len = 0);
+std::string mbcsToUtf8(const std::string &str);
+
+// Convert wide codepage to UTF-8
+// On Windows, the wide codepage is UTF-16
+// On Linux, the wide codepage is UTF-32
+std::string wideToUtf8(const wchar_t *str, size_t len = 0);
+std::string wideToUtf8(const std::wstring &str);
+
+// Convert UTF-8 to wide character set
+std::wstring utf8ToWide(const char *str, size_t len = 0);
+std::wstring utf8ToWide(const std::string &str);
+
+// Convert UTF-8 to local multibyte character set
+std::string utf8ToMbcs(const char *str, size_t len = 0);
+std::string utf8ToMbcs(const std::string &str);
+
+// Convert wide to local multibyte character set
+std::string wideToMbcs(const wchar_t *str, size_t len = 0);
+std::string wideToMbcs(const std::wstring &str);
+
+// Convert local multibyte to wide character set
+std::wstring mbcsToWide(const char *str, size_t len = 0);
+std::wstring mbcsToWide(const std::string &str);
+
+inline const char* asCStr(const char *str) { return str; }
+inline const char* asCStr(const std::string &str) { return str.c_str(); }
+inline const wchar_t* asCStr(const wchar_t *str) { return str; }
+inline const wchar_t* asCStr(const std::wstring &str) { return str.c_str(); }
+
+#if defined(NL_OS_WINDOWS)
+#define nlUtf8ToMbcs(str) (NLMISC::utf8ToMbcs(str).c_str())
+#define nlMbcsToUtf8(str) (NLMISC::mbcsToUtf8(str).c_str())
+#else
+#define nlUtf8ToMbcs(str) (NLMISC::asCStr(str))
+#define nlMbcsToUtf8(str) (NLMISC::asCStr(str))
+#endif
+#define nlWideToUtf8(str) (NLMISC::wideToUtf8(str).c_str())
+#define nlUtf8ToWide(str) (NLMISC::utf8ToWide(str).c_str()
+#define nlWideToMbcs(str) (NLMISC::wideToMbcs(str).c_str())
+#define nlMbcsToWide(str) (NLMISC::mbcsToWide(str).c_str())
+
+// On Windows, tstring is either local multibyte or utf-16 wide
+// On Linux, tstring is always utf-8
+
+#if defined(NL_OS_WINDOWS) && (defined(UNICODE) || defined(_UNICODE))
+typedef std::wstring tstring;
+typedef wchar_t tchar;
+#define nltmain wmain
+inline std::string tStrToUtf8(const tchar *str) { return wideToUtf8((const wchar_t *)str); }
+inline std::string tStrToUtf8(const tstring &str) { return wideToUtf8((const std::wstring &)str); }
+inline std::wstring tStrToWide(const tchar *str) { return (const wchar_t *)str; }
+inline std::wstring tStrToWide(const tstring &str) { return (const std::wstring &)str; }
+inline std::string tStrToMbcs(const tchar *str) { return wideToMbcs((const wchar_t *)str); }
+inline std::string tStrToMbcs(const tstring &str) { return wideToMbcs((const std::wstring &)str); }
+#define nlTStrToUtf8(str) (NLMISC::tStrToUtf8(str).c_str())
+#define nlTStrToWide(str) ((const wchar_t *)NLMISC::asCStr(str))
+#define nlTStrToMbcs(str) (NLMISC::tStrToMbcs(str).c_str())
+inline tstring utf8ToTStr(const char *str) {return (const tstring &)utf8ToWide(str); }
+inline tstring utf8ToTStr(const std::string &str) { return (const tstring &)utf8ToWide(str); }
+inline tstring wideToTStr(const wchar_t *str) { return (const tchar *)str; }
+inline tstring wideToTStr(const std::wstring &str) { return (const tstring &)str; }
+inline tstring mbcsToTStr(const char *str) { return (const tstring &)mbcsToWide(str); }
+inline tstring mbcsToTStr(const std::string &str) { return (const tstring &)mbcsToWide(str); }
+#define nlUtf8ToTStr(str) (NLMISC::utf8ToTStr(str).c_str())
+#define nlWideToTStr(str) ((const tchar *)NLMISC::asCStr(str))
+#define nlMbcsToTStr(str) (NLMISC::mbcsToTStr(str).c_str())
+#else
+typedef std::string tstring;
+typedef char tchar;
+#define nltmain main
+inline std::string tStrToUtf8(const tchar *str) { return mbcsToUtf8((const char *)str); }
+inline std::string tStrToUtf8(const tstring &str) { return mbcsToUtf8((const std::string &)str); }
+inline std::wstring tStrToWide(const tchar *str) { return mbcsToWide((const char *)str); }
+inline std::wstring tStrToWide(const tstring &str) { return mbcsToWide((const std::string &)str); }
+inline std::string tStrToMbcs(const tchar *str) { return (const char *)str; }
+inline std::string tStrToMbcs(const tstring &str) { return (const std::string &)str; }
+#if defined(NL_OS_WINDOWS)
+#define nlTStrToUtf8(str) (NLMISC::tStrToUtf8(str).c_str())
+#else
+#define nlTStrToUtf8(str) ((const char *)NLMISC::asCStr(str))
+#endif
+#define nlTStrToWide(str) (NLMISC::tStrToWide(str).c_str())
+#define nlTStrToMbcs(str) ((const char *)NLMISC::asCStr(str))
+inline tstring utf8ToTStr(const char *str) { return (const tstring &)utf8ToMbcs(str); }
+inline tstring utf8ToTStr(const std::string &str) { return (const tstring &)utf8ToMbcs(str); }
+inline tstring wideToTStr(const wchar_t *str) { return (const tstring &)wideToMbcs(str); }
+inline tstring wideToTStr(const std::wstring &str) { return (const tstring &)wideToMbcs(str); }
+inline tstring mbcsToTStr(const char *str) { return (const tchar *)str; }
+inline tstring mbcsToTStr(const std::string &str) { return (const tstring &)str; }
+#if defined(NL_OS_WINDOWS)
+#define nlUtf8ToTStr(str) (NLMISC::utf8ToTStr(str).c_str())
+#else
+#define nlUtf8ToTStr(str) ((const tchar *)NLMISC::asCStr(str))
+#endif
+#define nlWideToTStr(str) (NLMISC::wideToTStr(str).c_str())
+#define nlMbcsToTStr(str) ((const tchar *)NLMISC::asCStr(str))
+#endif
 
 } // NLMISC
 
diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h
index 1a1da7be2..27d147ffd 100644
--- a/code/nel/include/nel/misc/types_nl.h
+++ b/code/nel/include/nel/misc/types_nl.h
@@ -173,6 +173,12 @@
 #	define NL_NO_EXCEPTION_SPECS
 #endif
 
+#if defined(NL_COMP_VC) && (NL_COMP_VC_VERSION >= 140)
+#define nlmove(v) std::move(v)
+#else
+#define nlmove(v) (v)
+#endif
+
 // gcc 3.4 introduced ISO C++ with tough template rules
 //
 // NL_ISO_SYNTAX can be used using #if NL_ISO_SYNTAX or #if !NL_ISO_SYNTAX
diff --git a/code/nel/src/misc/string_common.cpp b/code/nel/src/misc/string_common.cpp
index 9c9085e4e..3c8913ce1 100644
--- a/code/nel/src/misc/string_common.cpp
+++ b/code/nel/src/misc/string_common.cpp
@@ -17,23 +17,24 @@
 #include "stdmisc.h"
 
 #include "nel/misc/string_common.h"
+#include "nel/misc/sstring.h"
 
 using namespace std;
 
 #ifdef DEBUG_NEW
-	#define new DEBUG_NEW
+#define new DEBUG_NEW
 #endif
 
 namespace NLMISC
 {
 
-string addSlashR (const string &str)
+string addSlashR(const string &str)
 {
 	string formatedStr;
 	// replace \n with \r\n
 	for (uint i = 0; i < str.size(); i++)
 	{
-		if (str[i] == '\n' && i > 0 && str[i-1] != '\r')
+		if (str[i] == '\n' && i > 0 && str[i - 1] != '\r')
 		{
 			formatedStr += '\r';
 		}
@@ -42,7 +43,7 @@ string addSlashR (const string &str)
 	return formatedStr;
 }
 
-string removeSlashR (const string &str)
+string removeSlashR(const string &str)
 {
 	string formatedStr;
 	// remove \r
@@ -54,4 +55,267 @@ string removeSlashR (const string &str)
 	return formatedStr;
 }
 
+bool fromString(const std::string &str, bool &val)
+{
+	if (str.length() == 1)
+	{
+		const char c = str[0];
+
+		switch (c)
+		{
+		case '1':
+		case 't':
+		case 'T':
+		case 'y':
+		case 'Y':
+			val = true;
+			break;
+
+		case '0':
+		case 'f':
+		case 'F':
+		case 'n':
+		case 'N':
+			val = false;
+			break;
+
+		default:
+			val = false;
+			return false;
+		}
+	}
+	else
+	{
+		std::string strl = toLower(str);
+		if (strl == "true" || strl == "yes")
+		{
+			val = true;
+		}
+		else if (strl == "false" || strl == "no")
+		{
+			val = false;
+		}
+		else
+		{
+			val = false;
+			return false;
+		}
+	}
+
+	return true;
+}
+
+#if defined(NL_OS_WINDOWS)
+
+std::string winWideToCp(const wchar_t *str, size_t len, UINT cp)
+{
+	if (!len)
+		len = wcslen(str);
+	if (!len)
+		return std::string();
+
+	// Convert from wide to codepage
+	char *tmp = (char *)_malloca((len + 1) * 4);
+	if (!tmp)
+		return std::string();
+	int tmpLen = WideCharToMultiByte(cp, 0,
+	    str, (int)(len + 1),
+	    tmp, (int)((len + 1) * 4),
+	    NULL, NULL);
+	if (tmpLen <= 1)
+	{
+		_freea(tmp);
+		return std::string();
+	}
+
+	std::string res = tmp;
+	_freea(tmp);
+	return res;
+}
+
+std::string winCpToCp(const char *str, size_t len, UINT srcCp, UINT dstCp)
+{
+	if (!len)
+		len = strlen(str);
+	if (!len)
+		return std::string();
+
+	// First convert from codepage to wide
+	wchar_t *tmp = (wchar_t *)_malloca((len + 1) * 4);
+	if (!tmp)
+		return std::string();
+	int tmpLen = MultiByteToWideChar(srcCp, MB_PRECOMPOSED,
+	    str, (int)(len + 1), /* include null-termination */
+	    tmp, (int)((len + 1) * 4));
+	if (tmpLen <= 1)
+	{
+		_freea(tmp);
+		return std::string();
+	}
+
+	// Then convert from wide to codepage
+	std::string res = winWideToCp(tmp, (size_t)tmpLen - 1, dstCp); /* tmpLen includes null-term */
+	_freea(tmp);
+	return res;
+}
+
+std::wstring winCpToWide(const char *str, size_t len, UINT cp)
+{
+	if (!len)
+		len = strlen(str);
+	if (!len)
+		return std::wstring();
+
+	// Convert from codepage to wide
+	wchar_t *tmp = (wchar_t *)_malloca((len + 1) * 4);
+	if (!tmp)
+		return std::wstring();
+	int tmpLen = MultiByteToWideChar(cp, MB_PRECOMPOSED,
+	    str, (int)(len + 1), /* include null-termination */
+	    tmp, (int)((len + 1) * 4));
+	if (tmpLen <= 1)
+	{
+		_freea(tmp);
+		return std::wstring();
+	}
+
+	std::wstring res = tmp;
+	_freea(tmp);
+	return res;
+}
+
+#endif
+
+// Convert local codepage to UTF-8
+// On Windows, the local codepage is undetermined
+// On Linux, the local codepage is always UTF-8 (no-op)
+std::string mbcsToUtf8(const char *str, size_t len)
+{
+#if defined(NL_OS_WINDOWS)
+	UINT codePage = GetACP();
+	// Windows 10 allows setting the local codepage to UTF-8
+	if (codePage == CP_UTF8) /* 65001 */
+		return str;
+	return winCpToCp(str, len, CP_ACP, CP_UTF8);
+#else
+	return str; /* no-op */
+#endif
+}
+
+std::string mbcsToUtf8(const std::string &str)
+{
+#if defined(NL_OS_WINDOWS)
+	if (str.empty())
+		return str;
+	UINT codePage = GetACP();
+	// Windows 10 allows setting the local codepage to UTF-8
+	if (codePage == CP_UTF8) /* 65001 */
+		return str;
+	return winCpToCp(str.c_str(), str.size(), CP_ACP, CP_UTF8);
+#else
+	return str; /* no-op */
+#endif
+}
+
+// Convert wide codepage to UTF-8
+// On Windows, the wide codepage is UTF-16
+// On Linux, the wide codepage is UTF-32
+std::string wideToUtf8(const wchar_t *str, size_t len)
+{
+#if defined(NL_OS_WINDOWS)
+	return winWideToCp(str, len, CP_UTF8);
+#else
+	// TODO: UTF-32 to UTF-8
+	nlassert(false);
+#endif
+}
+
+std::string wideToUtf8(const std::wstring &str)
+{
+	return wideToUtf8(str.c_str(), str.size());
+}
+
+// Convert UTF-8 to wide character set
+std::wstring utf8ToWide(const char *str, size_t len)
+{
+#if defined(NL_OS_WINDOWS)
+	return winCpToWide(str, len, CP_UTF8);
+#else
+	// TODO: UTF-32 to UTF-8
+	nlassert(false);
+#endif
+}
+
+std::wstring utf8ToWide(const std::string &str)
+{
+	return utf8ToWide(str.c_str(), str.size());
+}
+
+// Convert UTF-8 to local multibyte character set
+std::string utf8ToMbcs(const char *str, size_t len)
+{
+#if defined(NL_OS_WINDOWS)
+	UINT codePage = GetACP();
+	// Windows 10 allows setting the local codepage to UTF-8
+	if (codePage == CP_UTF8) /* 65001 */
+		return str;
+	return winCpToCp(str, len, CP_UTF8, CP_ACP);
+#else
+	return str; /* no-op */
+#endif
+}
+
+std::string utf8ToMbcs(const std::string &str)
+{
+#if defined(NL_OS_WINDOWS)
+	if (str.empty())
+		return str;
+	UINT codePage = GetACP();
+	// Windows 10 allows setting the local codepage to UTF-8
+	if (codePage == CP_UTF8) /* 65001 */
+		return str;
+	return winCpToCp(str.c_str(), str.size(), CP_UTF8, CP_ACP);
+#else
+	return str; /* no-op */
+#endif
+}
+
+// Convert wide to local multibyte character set
+std::string wideToMbcs(const wchar_t *str, size_t len)
+{
+#if defined(NL_OS_WINDOWS)
+	return winWideToCp(str, len, CP_ACP);
+#else
+	return wideToUTf8(str, len);
+#endif
+}
+
+std::string wideToMbcs(const std::wstring &str)
+{
+#if defined(NL_OS_WINDOWS)
+	return winWideToCp(str.c_str(), str.size(), CP_ACP);
+#else
+	return wideToUTf8(str);
+#endif
+}
+
+// Convert local multibyte to wide character set
+std::wstring mbcsToWide(const char *str, size_t len)
+{
+#if defined(NL_OS_WINDOWS)
+	return winCpToWide(str, len, CP_ACP);
+#else
+	return utf8ToWide(str, len);
+#endif
+}
+
+std::wstring mbcsToWide(const std::string &str)
+{
+#if defined(NL_OS_WINDOWS)
+	return winCpToWide(str.c_str(), str.size(), CP_ACP);
+#else
+	return utf8ToWide(str);
+#endif
+}
+
 }

From 842deeaa698ceb98795c2aa7d68e6750a204a004 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 05:59:03 +0800
Subject: [PATCH 43/75] Cleaning up unicode conversion

---
 code/nel/include/nel/misc/common.h            |  12 +-
 code/nel/include/nel/misc/string_common.h     |   4 +-
 code/nel/include/nel/misc/system_utils.h      |   4 +-
 code/nel/include/nel/misc/types_nl.h          |   9 ++
 code/nel/src/misc/common.cpp                  |   8 +-
 code/nel/src/misc/debug.cpp                   |   4 +-
 code/nel/src/misc/displayer.cpp               |  12 +-
 code/nel/src/misc/dynloadlib.cpp              |   2 +-
 code/nel/src/misc/path.cpp                    |  24 ++--
 code/nel/src/misc/system_info.cpp             |   2 +-
 code/nel/src/misc/system_utils.cpp            |  27 ++---
 code/nel/src/misc/win_displayer.cpp           |   2 +-
 code/nel/tools/3d/tile_edit/Browse.cpp        |  14 ++-
 .../tools/misc/data_mirror/data_mirror.cpp    |  24 ++--
 .../multi_cd_setup_fix/multi_cd_setup_fix.cpp |  61 ++++++-----
 .../common/src/game_share/login_registry.cpp  |   7 +-
 .../leveldesign/georges_dll/georges_edit.cpp  |  16 +--
 .../georges_dll/memory_combo_box.cpp          |  16 +--
 .../leveldesign/georges_dll/reg_shell_ext.cpp | 103 ++++++++++--------
 .../world_editor/file_dialog_ex.cpp           |  18 +--
 .../DialogFlags.cpp                           |   4 +-
 .../memory_combo_box.cpp                      |  26 ++---
 22 files changed, 207 insertions(+), 192 deletions(-)

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index 48468d6fd..c385af463 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -310,15 +310,15 @@ inline sint nlstricmp(const char *lhs, const std::string &rhs) { return stricmp(
 
 // Macros helper to convert UTF-8 std::string and TCHAR*
 #ifdef _UNICODE
-#define tStrToUtf8(str) (ucstring((ucchar*)(LPCWSTR)str).toUtf8())
-#define utf8ToTStr(str) ((const wchar_t *)ucstring::makeFromUtf8(str).c_str())
+// #define tStrToUtf8(str) (ucstring((ucchar*)(LPCWSTR)str).toUtf8())
+// #define utf8ToTStr(str) ((const wchar_t *)ucstring::makeFromUtf8(str).c_str())
 // #define tstring wstring
 #else
 // FIXME: This is not accurate, it should be a conversion between local charset and utf8
-#define tStrToUtf8(str) (std::string((LPCSTR)str))
-inline const char *nlutf8ToTStr(const char *str) { return str; }
-inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
-#define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
+// #define tStrToUtf8(str) (std::string((LPCSTR)str))
+// inline const char *nlutf8ToTStr(const char *str) { return str; }
+// inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
+// #define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
 // #define tstring string
 #endif
 
diff --git a/code/nel/include/nel/misc/string_common.h b/code/nel/include/nel/misc/string_common.h
index 4b757b989..d21b75d43 100644
--- a/code/nel/include/nel/misc/string_common.h
+++ b/code/nel/include/nel/misc/string_common.h
@@ -298,7 +298,7 @@ inline const wchar_t* asCStr(const std::wstring &str) { return str.c_str(); }
 #define nlMbcsToUtf8(str) (NLMISC::asCStr(str))
 #endif
 #define nlWideToUtf8(str) (NLMISC::wideToUtf8(str).c_str())
-#define nlUtf8ToWide(str) (NLMISC::utf8ToWide(str).c_str()
+#define nlUtf8ToWide(str) (NLMISC::utf8ToWide(str).c_str())
 #define nlWideToMbcs(str) (NLMISC::wideToMbcs(str).c_str())
 #define nlMbcsToWide(str) (NLMISC::mbcsToWide(str).c_str())
 
@@ -308,7 +308,6 @@ inline const wchar_t* asCStr(const std::wstring &str) { return str.c_str(); }
 #if defined(NL_OS_WINDOWS) && (defined(UNICODE) || defined(_UNICODE))
 typedef std::wstring tstring;
 typedef wchar_t tchar;
-#define nltmain wmain
 inline std::string tStrToUtf8(const tchar *str) { return wideToUtf8((const wchar_t *)str); }
 inline std::string tStrToUtf8(const tstring &str) { return wideToUtf8((const std::wstring &)str); }
 inline std::wstring tStrToWide(const tchar *str) { return (const wchar_t *)str; }
@@ -330,7 +329,6 @@ inline tstring mbcsToTStr(const std::string &str) { return (const tstring &)mbcs
 #else
 typedef std::string tstring;
 typedef char tchar;
-#define nltmain main
 inline std::string tStrToUtf8(const tchar *str) { return mbcsToUtf8((const char *)str); }
 inline std::string tStrToUtf8(const tstring &str) { return mbcsToUtf8((const std::string &)str); }
 inline std::wstring tStrToWide(const tchar *str) { return mbcsToWide((const char *)str); }
diff --git a/code/nel/include/nel/misc/system_utils.h b/code/nel/include/nel/misc/system_utils.h
index b6f121d94..c51a5ab99 100644
--- a/code/nel/include/nel/misc/system_utils.h
+++ b/code/nel/include/nel/misc/system_utils.h
@@ -70,10 +70,10 @@ public:
 	static void setRootKey(const std::string &root);
 
 	/// Read a value from registry.
-	static std::string getRegKey(const std::string &Entry);
+	static std::string getRegKey(const std::string &entry);
 
 	/// Write a value to registry.
-	static bool setRegKey(const std::string &ValueName, const std::string &Value);
+	static bool setRegKey(const std::string &valueName, const std::string &value);
 
 	/// Get desktop current color depth without using UDriver.
 	static uint getCurrentColorDepth();
diff --git a/code/nel/include/nel/misc/types_nl.h b/code/nel/include/nel/misc/types_nl.h
index 27d147ffd..353f50490 100644
--- a/code/nel/include/nel/misc/types_nl.h
+++ b/code/nel/include/nel/misc/types_nl.h
@@ -526,6 +526,15 @@ template<> struct hash<uint64>
  */
 typedef	uint16	ucchar;
 
+#if defined(NL_OS_WINDOWS) && (defined(UNICODE) || defined(_UNICODE))
+#define nltmain wmain
+#define nltWinMain wWinMain
+#else
+#define nltmain main
+#if defined(NL_OS_WINDOWS)
+#define nltWinMain WinMain
+#endif
+#endif
 
 // To define a 64bits constant; ie: UINT64_CONSTANT(0x123456781234)
 #ifdef NL_COMP_VC
diff --git a/code/nel/src/misc/common.cpp b/code/nel/src/misc/common.cpp
index 72f29eb82..bb7cf0bcd 100644
--- a/code/nel/src/misc/common.cpp
+++ b/code/nel/src/misc/common.cpp
@@ -911,7 +911,7 @@ static bool createProcess(const std::string &programName, const std::string &arg
 	}
 
 	// or 0 for a window
-	BOOL res = CreateProcessW(sProgramName, utf8ToWide(args), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL /* current dir */, &si, &pi);
+	BOOL res = CreateProcessW(sProgramName, (LPWSTR)nlUtf8ToWide(args), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL /* current dir */, &si, &pi);
 
 	if (sProgramName)
 	{
@@ -1453,7 +1453,7 @@ void displayDwordBits( uint32 b, uint nbits, sint beginpos, bool displayBegin, N
 FILE* nlfopen(const std::string &filename, const std::string &mode)
 {
 #ifdef NL_OS_WINDOWS
-	return _wfopen(utf8ToWide(filename), utf8ToWide(mode));
+	return _wfopen(nlUtf8ToWide(filename), nlUtf8ToWide(mode));
 #else
 	return fopen(filename.c_str(), mode.c_str());
 #endif
@@ -1632,7 +1632,7 @@ static bool openDocWithExtension (const std::string &document, const std::string
 {
 #ifdef NL_OS_WINDOWS
 	// First try ShellExecute()
-	HINSTANCE result = ShellExecuteW(NULL, L"open", utf8ToWide(document), NULL, NULL, SW_SHOWDEFAULT);
+	HINSTANCE result = ShellExecuteW(NULL, L"open", nlUtf8ToWide(document), NULL, NULL, SW_SHOWDEFAULT);
 
 	// If it failed, get the .htm regkey and lookup the program
 	if ((uintptr_t)result <= HINSTANCE_ERROR)
@@ -1640,7 +1640,7 @@ static bool openDocWithExtension (const std::string &document, const std::string
 		wchar_t key[MAX_PATH + MAX_PATH];
 
 		// get the type of the extension
-		if (GetRegKey(HKEY_CLASSES_ROOT, utf8ToWide("." + ext), key) == ERROR_SUCCESS)
+		if (GetRegKey(HKEY_CLASSES_ROOT, nlUtf8ToWide("." + ext), key) == ERROR_SUCCESS)
 		{
 			lstrcatW(key, L"\\shell\\open\\command");
 
diff --git a/code/nel/src/misc/debug.cpp b/code/nel/src/misc/debug.cpp
index c6d10b700..260834200 100644
--- a/code/nel/src/misc/debug.cpp
+++ b/code/nel/src/misc/debug.cpp
@@ -1431,7 +1431,7 @@ int getLastError()
 std::string formatErrorMessage(int errorCode)
 {
 #ifdef NL_OS_WINDOWS
-	LPVOID lpMsgBuf = NULL;
+	LPWSTR lpMsgBuf = NULL;
 	DWORD len = FormatMessageW(
 		FORMAT_MESSAGE_ALLOCATE_BUFFER |
 		FORMAT_MESSAGE_FROM_SYSTEM |
@@ -1439,7 +1439,7 @@ std::string formatErrorMessage(int errorCode)
 		NULL,
 		errorCode,
 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-		(LPWSTR) &lpMsgBuf,
+		(LPWSTR)(&lpMsgBuf),
 		0,
 		NULL
 	);
diff --git a/code/nel/src/misc/displayer.cpp b/code/nel/src/misc/displayer.cpp
index 8feaa9358..ba5cc85d0 100644
--- a/code/nel/src/misc/displayer.cpp
+++ b/code/nel/src/misc/displayer.cpp
@@ -286,14 +286,14 @@ void CStdDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mess
 			// WARNING: READ THIS !!!!!!!!!!!!!!!! ///////////////////////////
 			// If at the release time, it freezes here, it's a microsoft bug:
 			// http://support.microsoft.com/support/kb/articles/q173/2/60.asp
-			OutputDebugStringW(utf8ToWide(str2));
+			OutputDebugStringW(nlUtf8ToWide(str2));
 		}
 		else
 		{
 			sint count = 0;
 			uint n = (uint)strlen(message);
 			std::string s(&str2.c_str()[0], (str2.size() - n));
-			OutputDebugStringW(utf8ToWide(s));
+			OutputDebugStringW(nlUtf8ToWide(s));
 
 			for(;;)
 			{
@@ -301,14 +301,14 @@ void CStdDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mess
 				if((n - count) < maxOutString )
 				{
 					s = std::string(&message[count], (n - count));
-					OutputDebugStringW(utf8ToWide(s));
+					OutputDebugStringW(nlUtf8ToWide(s));
 					OutputDebugStringW(L"\n");
 					break;
 				}
 				else
 				{
 					s = std::string(&message[count] , count + maxOutString);
-					OutputDebugStringW(utf8ToWide(s));
+					OutputDebugStringW(nlUtf8ToWide(s));
 					OutputDebugStringW(L"\n\t\t\t");
 					count += maxOutString;
 				}
@@ -323,13 +323,13 @@ void CStdDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *mess
 			if (pos+1000 < args.CallstackAndLog.size ())
 			{
 				splited = args.CallstackAndLog.substr (pos, 1000);
-				OutputDebugStringW(utf8ToWide(splited));
+				OutputDebugStringW(nlUtf8ToWide(splited));
 				pos += 1000;
 			}
 			else
 			{
 				splited = args.CallstackAndLog.substr (pos);
-				OutputDebugStringW(utf8ToWide(splited));
+				OutputDebugStringW(nlUtf8ToWide(splited));
 				break;
 			}
 		}
diff --git a/code/nel/src/misc/dynloadlib.cpp b/code/nel/src/misc/dynloadlib.cpp
index 66f774fa2..a36c02f17 100644
--- a/code/nel/src/misc/dynloadlib.cpp
+++ b/code/nel/src/misc/dynloadlib.cpp
@@ -32,7 +32,7 @@ NL_LIB_HANDLE nlLoadLibrary(const std::string &libName)
 {
 	NL_LIB_HANDLE res = 0;
 #ifdef NL_OS_WINDOWS
-	res = LoadLibraryW(utf8ToWide(libName));
+	res = LoadLibraryW(nlUtf8ToWide(libName));
 #elif defined(NL_OS_UNIX)
 	res = dlopen(libName.c_str(), RTLD_NOW);
 #else
diff --git a/code/nel/src/misc/path.cpp b/code/nel/src/misc/path.cpp
index c6f9786f4..0c650918f 100644
--- a/code/nel/src/misc/path.cpp
+++ b/code/nel/src/misc/path.cpp
@@ -700,7 +700,7 @@ bool CFileContainer::setCurrentPath (const std::string &path)
 	int res;
 	//nldebug("Change current path to '%s' (current path is '%s')", path.c_str(), getCurrentPath().c_str());
 #ifdef NL_OS_WINDOWS
-	res = _wchdir(utf8ToWide(path));
+	res = _wchdir(nlUtf8ToWide(path));
 #else
 	res = chdir(path.c_str());
 #endif
@@ -792,7 +792,7 @@ dirent *readdir (DIR *dir)
 	// first visit in this directory : FindFirstFile()
 	if (hFind == NULL)
 	{
-		hFind = FindFirstFileW (utf8ToWide(CPath::standardizePath(sDir) + "*"), &findData);
+		hFind = FindFirstFileW(nlUtf8ToWide(CPath::standardizePath(sDir) + "*"), &findData);
 	}
 	// directory already visited : FindNextFile()
 	else
@@ -1914,7 +1914,7 @@ string CFile::getPath (const string &filename)
 bool CFile::isDirectory (const string &filename)
 {
 #ifdef NL_OS_WINDOWS
-	DWORD res = GetFileAttributesW(utf8ToWide(filename));
+	DWORD res = GetFileAttributesW(nlUtf8ToWide(filename));
 	if (res == INVALID_FILE_ATTRIBUTES)
 	{
 		// nlwarning ("PATH: '%s' is not a valid file or directory name", filename.c_str ());
@@ -1937,7 +1937,7 @@ bool CFile::isDirectory (const string &filename)
 bool CFile::isExists (const string &filename)
 {
 #ifdef NL_OS_WINDOWS
-	return GetFileAttributesW(utf8ToWide(filename)) != INVALID_FILE_ATTRIBUTES;
+	return GetFileAttributesW(nlUtf8ToWide(filename)) != INVALID_FILE_ATTRIBUTES;
 #else // NL_OS_WINDOWS
 	struct stat buf;
 	return stat (filename.c_str (), &buf) == 0;
@@ -2017,7 +2017,7 @@ uint32	CFile::getFileSize (const std::string &filename)
 	{
 #if defined (NL_OS_WINDOWS)
 		struct _stat buf;
-		int result = _wstat (utf8ToWide(filename), &buf);
+		int result = _wstat(nlUtf8ToWide(filename), &buf);
 #elif defined (NL_OS_UNIX)
 		struct stat buf;
 		int result = stat (filename.c_str (), &buf);
@@ -2068,7 +2068,7 @@ uint32	CFile::getFileModificationDate(const std::string &filename)
 	// Use the WIN32 API to read the file times in UTC
 
 	// create a file handle (this does not open the file)
-	HANDLE h = CreateFileW(utf8ToWide(fn), 0, 0, NULL, OPEN_EXISTING, 0, 0);
+	HANDLE h = CreateFileW(nlUtf8ToWide(fn), 0, 0, NULL, OPEN_EXISTING, 0, 0);
 	if (h == INVALID_HANDLE_VALUE)
 	{
 		nlwarning("Can't get modification date on file '%s' : %s", fn.c_str(), NLMISC::formatErrorMessage(NLMISC::getLastError()).c_str());
@@ -2138,7 +2138,7 @@ bool	CFile::setFileModificationDate(const std::string &filename, uint32 modTime)
 	// Use the WIN32 API to set the file times in UTC
 
 	// create a file handle (this does not open the file)
-	HANDLE h = CreateFileW(utf8ToWide(fn), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+	HANDLE h = CreateFileW(nlUtf8ToWide(fn), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
 	if (h == INVALID_HANDLE_VALUE)
 	{
 		nlwarning("Can't set modification date on file '%s' (error accessing file) : %s", fn.c_str(), NLMISC::formatErrorMessage(NLMISC::getLastError()).c_str());
@@ -2223,7 +2223,7 @@ uint32	CFile::getFileCreationDate(const std::string &filename)
 
 #if defined (NL_OS_WINDOWS)
 	struct _stat buf;
-	int result = _wstat(utf8ToWide(fn), &buf);
+	int result = _wstat(nlUtf8ToWide(fn), &buf);
 #elif defined (NL_OS_UNIX)
 	struct stat buf;
 	int result = stat(fn.c_str (), &buf);
@@ -2357,7 +2357,7 @@ static bool CopyMoveFile(const std::string &dest, const std::string &src, bool c
 	else
 	{
 #ifdef NL_OS_WINDOWS
-		if (MoveFileW(utf8ToWide(ssrc), utf8ToWide(sdest)) == 0)
+		if (MoveFileW(nlUtf8ToWide(ssrc), nlUtf8ToWide(sdest)) == 0)
 		{
 			sint lastError = NLMISC::getLastError();
 			nlwarning ("PATH: CopyMoveFile error: can't link/move '%s' into '%s', error %u (%s)",
@@ -2482,7 +2482,7 @@ bool CFile::moveFile(const std::string &dest, const std::string &src)
 bool CFile::createDirectory(const std::string &filename)
 {
 #ifdef NL_OS_WINDOWS
-	return _wmkdir(utf8ToWide(filename))==0;
+	return _wmkdir(nlUtf8ToWide(filename)) == 0;
 #else
 	// Set full permissions....
 	return mkdir(filename.c_str(), 0xFFFF)==0;
@@ -2751,7 +2751,7 @@ bool CFile::deleteFile(const std::string &filename)
 {
 	setRWAccess(filename);
 #ifdef NL_OS_WINDOWS
-	sint res = _wunlink(utf8ToWide(filename));
+	sint res = _wunlink(nlUtf8ToWide(filename));
 #else
 	sint res = unlink(filename.c_str());
 #endif
@@ -2770,7 +2770,7 @@ bool CFile::deleteDirectory(const std::string &filename)
 {
 	setRWAccess(filename);
 #ifdef NL_OS_WINDOWS
-	sint res = _wrmdir(utf8ToWide(filename));
+	sint res = _wrmdir(nlUtf8ToWide(filename));
 #else
 	sint res = rmdir(filename.c_str());
 #endif
diff --git a/code/nel/src/misc/system_info.cpp b/code/nel/src/misc/system_info.cpp
index 75d9707b3..3e8c296d3 100644
--- a/code/nel/src/misc/system_info.cpp
+++ b/code/nel/src/misc/system_info.cpp
@@ -1460,7 +1460,7 @@ uint64 CSystemInfo::availableHDSpace (const string &filename)
 	return (uint64)stfs.f_bavail * (uint64)stfs.f_bsize;
 #else
 	ULARGE_INTEGER freeSpace = {0};
-	BOOL bRes = ::GetDiskFreeSpaceExW(utf8ToWide(path), &freeSpace, NULL, NULL);
+	BOOL bRes = ::GetDiskFreeSpaceExW(nlUtf8ToWide(path), &freeSpace, NULL, NULL);
 	if (!bRes) return 0;
 
 	return (uint64)freeSpace.QuadPart;
diff --git a/code/nel/src/misc/system_utils.cpp b/code/nel/src/misc/system_utils.cpp
index 480e1c9a1..3655bc70c 100644
--- a/code/nel/src/misc/system_utils.cpp
+++ b/code/nel/src/misc/system_utils.cpp
@@ -323,58 +323,55 @@ void CSystemUtils::setRootKey(const std::string &root)
 	RootKey = root;
 }
 
-string CSystemUtils::getRegKey(const string &Entry)
+string CSystemUtils::getRegKey(const string &entry)
 {
 	string ret;
 #ifdef NL_OS_WINDOWS
 	HKEY hkey;
 
-	if (RegOpenKeyExW(HKEY_CURRENT_USER, utf8ToWide(RootKey), 0, KEY_READ, &hkey) == ERROR_SUCCESS)
+	if (RegOpenKeyExW(HKEY_CURRENT_USER, nlUtf8ToWide(RootKey), 0, KEY_READ, &hkey) == ERROR_SUCCESS)
 	{
 		DWORD	dwType	= 0L;
 		DWORD	dwSize	= KeyMaxLength;
-		wchar_t Buffer[KeyMaxLength];
+		wchar_t buffer[KeyMaxLength];
 
-		if (RegQueryValueExW(hkey, utf8ToWide(Entry), NULL, &dwType, (LPBYTE)Buffer, &dwSize) != ERROR_SUCCESS)
+		if (RegQueryValueExW(hkey, nlUtf8ToWide(entry), NULL, &dwType, (LPBYTE)buffer, &dwSize) != ERROR_SUCCESS)
 		{
-			nlwarning("Can't get the reg key '%s'", Entry.c_str());
+			nlwarning("Can't get the reg key '%s'", entry.c_str());
 		}
 		else
 		{
-			ret = wideToUtf8(Buffer);
+			ret = wideToUtf8(buffer);
 		}
 
 		RegCloseKey(hkey);
 	}
 	else
 	{
-		nlwarning("Can't get the reg key '%s'", Entry.c_str());
+		nlwarning("Can't get the reg key '%s'", entry.c_str());
 	}
 #endif
 	return ret;
 }
 
-bool CSystemUtils::setRegKey(const string &ValueName, const string &Value)
+bool CSystemUtils::setRegKey(const string &valueName, const string &value)
 {
 	bool res = false;
 #ifdef NL_OS_WINDOWS
 	HKEY hkey;
 	DWORD dwDisp;
 
-	if (RegCreateKeyExW(HKEY_CURRENT_USER, utf8ToWide(RootKey), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDisp) == ERROR_SUCCESS)
+	if (RegCreateKeyExW(HKEY_CURRENT_USER, nlUtf8ToWide(RootKey), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwDisp) == ERROR_SUCCESS)
 	{
-		ucstring utf16Value = ucstring::makeFromUtf8(Value);
-
 		// we must use the real Unicode string size in bytes
-		DWORD size = (utf16Value.length() + 1) * 2;
-
-		if (RegSetValueExW(hkey, utf8ToWide(ValueName), 0L, REG_SZ, (const BYTE *)utf16Value.c_str(), size) == ERROR_SUCCESS)
+		std::wstring wvalue = nlUtf8ToWide(value);
+		if (RegSetValueExW(hkey, nlUtf8ToWide(valueName), 0, REG_SZ, (const BYTE *)wvalue.c_str(), (wvalue.size() + 1) * sizeof(WCHAR)) == ERROR_SUCCESS)
 			res = true;
 		RegCloseKey(hkey);
 	}
 	else
 	{
-		nlwarning("Can't set the reg key '%s' '%s'", ValueName.c_str(), Value.c_str());
+		nlwarning("Can't set the reg key '%s' '%s'", valueName.c_str(), value.c_str());
 	}
 #endif
 
diff --git a/code/nel/src/misc/win_displayer.cpp b/code/nel/src/misc/win_displayer.cpp
index d350f25f3..03e1265b9 100644
--- a/code/nel/src/misc/win_displayer.cpp
+++ b/code/nel/src/misc/win_displayer.cpp
@@ -298,7 +298,7 @@ void CWinDisplayer::updateLabels ()
 					}
 				}
 
-				SendMessageW ((HWND)access.value()[i].Hwnd, WM_SETTEXT, 0, (LPARAM) utf8ToWide(n));
+				SendMessageW((HWND)access.value()[i].Hwnd, WM_SETTEXT, 0, (LPARAM)nlUtf8ToWide(n));
 				access.value()[i].NeedUpdate = false;
 			}
 		}
diff --git a/code/nel/tools/3d/tile_edit/Browse.cpp b/code/nel/tools/3d/tile_edit/Browse.cpp
index 89e45c62d..a0064456d 100644
--- a/code/nel/tools/3d/tile_edit/Browse.cpp
+++ b/code/nel/tools/3d/tile_edit/Browse.cpp
@@ -612,7 +612,7 @@ void Browse::Init()
 	unsigned long value; 
 	unsigned long type; 
 	int cx=-1,cy=-1,x=-1,y=-1;
-	char sWindowpl[256];
+	TCHAR sWindowpl[256];
 
 	if (RegOpenKey(HKEY_CURRENT_USER,REGKEY_TILEDIT,&regkey)==ERROR_SUCCESS)
 	{		
@@ -621,7 +621,7 @@ void Browse::Init()
 		if (RegQueryValueEx(regkey,REGKEY_WNDPL,0,&type,(unsigned char *)&sWindowpl,&value)==ERROR_SUCCESS)
 		{
 			WINDOWPLACEMENT wndpl;
-			sscanf(sWindowpl,"%d %d %d %d %d %d %d %d %d %d",
+			_stscanf(sWindowpl,_T("%d %d %d %d %d %d %d %d %d %d"),
 						&wndpl.flags,
 						&wndpl.ptMaxPosition.x,&wndpl.ptMaxPosition.y,
 						&wndpl.ptMinPosition.x,&wndpl.ptMinPosition.y,
@@ -632,10 +632,10 @@ void Browse::Init()
 		}
 		value=256;
 		type=REG_SZ;
-		if (RegQueryValueEx(regkey,REGKEY_LASTPATH,0,&type,(unsigned char *)&sWindowpl,&value)!=ERROR_SUCCESS)
+		if (RegQueryValueEx(regkey, REGKEY_LASTPATH, 0, &type, (unsigned char *)&sWindowpl, &value) != ERROR_SUCCESS)
 			m_ctrl.LastPath.clear();
 		else
-			m_ctrl.LastPath=(const char*)sWindowpl;
+			m_ctrl.LastPath = tStrToUtf8(sWindowpl);
 		value=4;
 		type=REG_DWORD;
 		if (RegQueryValueEx(regkey,REGKEY_BUTTONZOOM,0,&type,(unsigned char *)&m_ctrl.Zoom,&value)!=ERROR_SUCCESS) 
@@ -808,8 +808,10 @@ void Browse::OnDestroy()
 	if (RegCreateKey(HKEY_CURRENT_USER,REGKEY_TILEDIT,&regkey)==ERROR_SUCCESS)
 	{	
 		//int sel = ((CComboBox*)GetDlgItem(IDC_LISTTYPE))->GetCurSel();
-		RegSetValueEx(regkey,REGKEY_WNDPL,0,REG_SZ,(const unsigned char*)sWindowpl,(DWORD)strlen(sWindowpl));
-		RegSetValueEx(regkey,REGKEY_LASTPATH,0,REG_SZ,(const unsigned char*)m_ctrl.LastPath.c_str(),(DWORD)strlen(m_ctrl.LastPath.c_str()));
+		tstring tWindowpl = utf8ToTStr(sWindowpl);
+		tstring tLastPath = utf8ToTStr(m_ctrl.LastPath);
+		RegSetValueEx(regkey, REGKEY_WNDPL, 0, REG_SZ, (const BYTE *)tWindowpl.c_str(), (tWindowpl.size() + 1) * sizeof(TCHAR));
+		RegSetValueEx(regkey, REGKEY_LASTPATH, 0, REG_SZ, (const BYTE *)tLastPath.c_str(), (tLastPath.size() + 1) * sizeof(TCHAR));
 		RegSetValueEx(regkey,REGKEY_BUTTONZOOM,0,REG_DWORD,(const unsigned char*)&m_ctrl.Zoom,4);
 		RegSetValueEx(regkey,REGKEY_BUTTONVARIETY,0,REG_DWORD,(const unsigned char*)&m_128x128,4);
 		RegSetValueEx(regkey,REGKEY_BUTTONTEXTURE,0,REG_DWORD,(const unsigned char*)&m_ctrl.Texture,4);
diff --git a/code/nel/tools/misc/data_mirror/data_mirror.cpp b/code/nel/tools/misc/data_mirror/data_mirror.cpp
index 99a87f547..344ecc1ad 100644
--- a/code/nel/tools/misc/data_mirror/data_mirror.cpp
+++ b/code/nel/tools/misc/data_mirror/data_mirror.cpp
@@ -73,7 +73,7 @@ BOOL CData_mirrorApp::InitInstance()
 	{
 		// Get the module
 		CConfigFile	cf;
-		string exePath = GetCommandLine ();
+		string exePath = nlTStrToUtf8(GetCommandLineW());
 		if (exePath.size()>0)
 		{
 			if (exePath[0] == '\"')
@@ -124,7 +124,7 @@ BOOL CData_mirrorApp::InitInstance()
 		if ((sBinaryCompare == "true") || (sBinaryCompare=="1"))
 			BinaryCompare = true;
 
-		CurrentDir = m_lpCmdLine;
+		CurrentDir = nlTStrToUtf8(m_lpCmdLine);
 		// Remove 
 		if (CurrentDir.size ()>=2)
 		{
@@ -151,7 +151,7 @@ BOOL CData_mirrorApp::InitInstance()
 		}
 		else
 		{
-			MessageBox (NULL, (CurrentDir+" is not a directory nor a file.").c_str (), "NeL Data Mirror", MB_OK|MB_ICONEXCLAMATION);
+			MessageBox (NULL, nlUtf8ToTStr(CurrentDir+" is not a directory nor a file."), _T("NeL Data Mirror"), MB_OK|MB_ICONEXCLAMATION);
 			return FALSE;
 		}
 
@@ -168,8 +168,8 @@ BOOL CData_mirrorApp::InitInstance()
 			}
 			else
 			{
-				MessageBox (NULL, (CurrentDir+" is not a sub directory of "+MainDirectory+" or "+MirrorDirectory).c_str (), 
-							"NeL Data Mirror", MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(NULL, nlUtf8ToTStr(CurrentDir + " is not a sub directory of " + MainDirectory + " or " + MirrorDirectory), 
+							_T("NeL Data Mirror"), MB_OK|MB_ICONEXCLAMATION);
 				return FALSE;
 			}
 		}
@@ -200,7 +200,7 @@ BOOL CData_mirrorApp::InitInstance()
 	}
 	catch (const Exception &e)
 	{
-		MessageBox (NULL, e.what (), "NeL Data Mirror", MB_OK|MB_ICONEXCLAMATION);
+		MessageBox(NULL, nlUtf8ToTStr(e.what()), _T("NeL Data Mirror"), MB_OK | MB_ICONEXCLAMATION);
 	}
 
 	CData_mirrorDlg dlg;
@@ -227,19 +227,21 @@ bool RegisterDirectoryAppCommand (const char *appName, const char *command, cons
 {
 	// Create the app key
 	HKEY hKey;
-	if (RegCreateKey (HKEY_CLASSES_ROOT, "Directory", &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey (HKEY_CLASSES_ROOT, _T("Directory"), &hKey) == ERROR_SUCCESS)
 	{
 		// Create the icon
 		char tmp[512];
 		smprintf (tmp, 512, "shell\\%s", appName);
-		if (RegCreateKey (hKey, tmp, &hKey) == ERROR_SUCCESS)
+		if (RegCreateKey(hKey, nlUtf8ToTStr(tmp), &hKey) == ERROR_SUCCESS)
 		{
 			// Set the description
-			RegSetValue (hKey, "", REG_SZ, command, (DWORD)strlen (command));
-			if (RegCreateKey (hKey, "command", &hKey) == ERROR_SUCCESS)
+			tstring tcommand = utf8ToTStr(command);
+			RegSetValue(hKey, _T(""), REG_SZ, tcommand.c_str(), (tcommand.size() + 1) * sizeof(TCHAR));
+			if (RegCreateKey (hKey, _T("command"), &hKey) == ERROR_SUCCESS)
 			{
 				// Set the description
-				RegSetValue (hKey, "", REG_SZ, app, (DWORD)strlen (app));
+				tstring tapp = utf8ToTStr(app);
+				RegSetValue(hKey, _T(""), REG_SZ, tapp.c_str(), (tapp.size() + 1) * sizeof(TCHAR));
 				return true;
 			}
 		}
diff --git a/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp b/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
index f7ef1a9fc..9e20c09a0 100644
--- a/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
+++ b/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
@@ -15,6 +15,7 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <windows.h>
+#include <tchar.h>
 #include <stdio.h>
 #include "resource.h"
 
@@ -40,7 +41,7 @@ void pump ()
 	}
 }
 
-int APIENTRY WinMain(HINSTANCE hInstance,
+int APIENTRY _tWinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPSTR     lpCmdLine,
                      int       nCmdShow)
@@ -57,68 +58,68 @@ int APIENTRY WinMain(HINSTANCE hInstance,
 	pump ();
 
  	// Get the temp directory
-	char tempPath[1024];
+	TCHAR tempPath[1024];
 	if (GetTempPath(1024, tempPath))
 	{
-		char pathToDelete[1024];
-		strcpy (pathToDelete, tempPath);
-		strcat (pathToDelete, "Ryzom");
+		TCHAR pathToDelete[1024];
+		_tcscpy (pathToDelete, tempPath);
+		_tcscat (pathToDelete, _T("Ryzom"));
 
 		CreateDirectory(tempPath, NULL);
-		strcat (tempPath, "Ryzom\\");
+		_tcscat (tempPath, _T("Ryzom\\"));
 		CreateDirectory(tempPath, NULL);
 
 		// Copy the files
 
 		pump ();
 		// Setup.dat
-		char setupFile[1024];
-		strcpy (setupFile, tempPath);
-		strcat (setupFile, "setup.exe");
+		TCHAR setupFile[1024];
+		_tcscpy (setupFile, tempPath);
+		_tcscat(setupFile, _T("setup.exe"));
 		SetFileAttributes(setupFile, GetFileAttributes(setupFile)&~FILE_ATTRIBUTE_READONLY);
 		BOOL deleted = DeleteFile (setupFile);
-		if (!CopyFile ("setup.dat", setupFile, FALSE) && deleted)
-			MessageBox (NULL, "Not enough disk space", "Setup", MB_OK|MB_ICONERROR);
+		if (!CopyFile (_T("setup.dat"), setupFile, FALSE) && deleted)
+			MessageBox (NULL, _T("Not enough disk space"), _T("Setup"), MB_OK|MB_ICONERROR);
 		SetFileAttributes(setupFile, GetFileAttributes(setupFile)&~FILE_ATTRIBUTE_READONLY);
 
 		pump ();
 		// Ryzom.msi
-		char msiFile[1024];
-		strcpy (msiFile, tempPath);
-		strcat (msiFile, "Ryzom.msi");
+		TCHAR msiFile[1024];
+		_tcscpy(msiFile, tempPath);
+		_tcscat(msiFile, _T("Ryzom.msi"));
 		SetFileAttributes(msiFile, GetFileAttributes(msiFile)&~FILE_ATTRIBUTE_READONLY);
 		deleted = DeleteFile (msiFile); 
-		if (!CopyFile ("Ryzom.msi", msiFile, FALSE) && deleted)
-			MessageBox (NULL, "Not enough disk space", "Setup", MB_OK|MB_ICONERROR);
+		if (!CopyFile (_T("Ryzom.msi"), msiFile, FALSE) && deleted)
+			MessageBox (NULL, _T("Not enough disk space"), _T("Setup"), MB_OK|MB_ICONERROR);
 		SetFileAttributes(msiFile, GetFileAttributes(msiFile)&~FILE_ATTRIBUTE_READONLY);
 
 		pump ();
 		// Generate the remove bat file
-		char batFile[1024];
-		strcpy (batFile, tempPath);
-		strcat (batFile, "remove.bat");
-		FILE *file = fopen (batFile, "w");
-		fprintf (file, "@echo off\nrmdir /S /Q \"%s\" > NUL\ndeltree /Y \"%s\" > NUL\n", pathToDelete, pathToDelete);
+		TCHAR batFile[1024];
+		_tcscpy (batFile, tempPath);
+		_tcscat(batFile, _T("remove.bat"));
+		FILE *file = _tfopen (batFile, _T("w"));
+		_ftprintf (file, _T("@echo off\nrmdir /S /Q \"%s\" > NUL\ndeltree /Y \"%s\" > NUL\n"), pathToDelete, pathToDelete);
 		fclose (file);
 
 		// Register the remove bat file
 		HKEY hKey;
-		RegCreateKey (HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Runonce", &hKey);
-		char batFileReg[1024];
-		sprintf (batFileReg, "\"%s\"", batFile);
-		RegSetValueEx(hKey, "RyzomSetupClean", 0, REG_SZ, (const unsigned char*)batFileReg, (DWORD)strlen (batFileReg)+1);
+		RegCreateKey (HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Runonce"), &hKey);
+		TCHAR batFileReg[1024];
+		_stprintf (batFileReg, _T("\"%s\""), batFile);
+		RegSetValueEx(hKey, _T("RyzomSetupClean"), 0, REG_SZ, (const unsigned char *)batFileReg, (DWORD)(_tcslen(batFileReg) + 1) * sizeof(TCHAR));
 
 		pump ();
 		// Get the current path
-		char currentPath[1024];
+		TCHAR currentPath[1024];
 		GetCurrentDirectory (1024, currentPath);
-		if (currentPath[strlen(currentPath)-1] == '\\')
-			currentPath[strlen(currentPath)-1] = 0;
+		if (currentPath[_tcslen(currentPath) - 1] == '\\')
+			currentPath[_tcslen(currentPath) - 1] = 0;
 
 		pump ();
 		// Build the command line : /z"f:\"
-		char option[1024];
-		sprintf (option, "\"%s\" /z\"%s\"", setupFile, currentPath);
+		TCHAR option[1024];
+		_stprintf(option, _T("\"%s\" /z\"%s\""), setupFile, currentPath);
 
 		pump ();
 		// Execute the setup
diff --git a/code/ryzom/common/src/game_share/login_registry.cpp b/code/ryzom/common/src/game_share/login_registry.cpp
index 7e0c68234..e30949400 100644
--- a/code/ryzom/common/src/game_share/login_registry.cpp
+++ b/code/ryzom/common/src/game_share/login_registry.cpp
@@ -39,7 +39,7 @@ std::string CLoginRegistry::getProductInstallId()
 		if (RegQueryValueExW(hKey, InstallIdKeyHandle, NULL, &dwType, (BYTE *) buffer, &dwSize) == ERROR_SUCCESS && dwType == REG_SZ)
 		{
 			RegCloseKey(hKey);
-			return wideToUtf8(buffer);
+			return NLMISC::wideToUtf8(buffer);
 		}
 		RegCloseKey(hKey);
 	}
@@ -58,10 +58,9 @@ std::string CLoginRegistry::getProductInstallId()
 
 		// copy wide string to a buffer
 		const uint keyMaxLength = 16;
-		wchar_t	buffer[keyMaxLength];
-		wcscpy(buffer, utf8ToWide(id));
+		std::wstring wid = NLMISC::utf8ToWide(id);
 
-		if (RegSetValueExW(hKey, InstallIdKeyHandle, 0L, REG_SZ, (const BYTE *) buffer, (DWORD)(wcslen(buffer)*2+2)) == ERROR_SUCCESS)
+		if (RegSetValueExW(hKey, InstallIdKeyHandle, 0L, REG_SZ, (const BYTE *)wid.c_str(), (DWORD)((wid.size() + 1) * sizeof(WCHAR))) == ERROR_SUCCESS)
 		{
 			return id;
 		}
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
index 9b62e3a1a..480fdfbe0 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit.cpp
@@ -477,9 +477,9 @@ void CGeorgesEditApp::OnAppAbout()
 void CGeorgesEditApp::outputError (const char* message)
 {
 	if (m_pMainWnd)
-		m_pMainWnd->MessageBox (utf8ToTStr(message), _T("Georges Edit"), MB_OK|MB_ICONEXCLAMATION);
+		m_pMainWnd->MessageBox(nlUtf8ToTStr(message), _T("Georges Edit"), MB_OK | MB_ICONEXCLAMATION);
 	else
-		MessageBox (NULL, utf8ToTStr(message), _T("Georges Edit"), MB_OK|MB_ICONEXCLAMATION);
+		MessageBox(NULL, nlUtf8ToTStr(message), _T("Georges Edit"), MB_OK | MB_ICONEXCLAMATION);
 }
 
 void CGeorgesEditApp::getConfigFilePath (std::string &output)
@@ -711,9 +711,9 @@ bool CGeorgesEditApp::getColor (NLMISC::CRGBA &color)
 bool CGeorgesEditApp::yesNo (const char* message)
 {
 	if (m_pMainWnd)
-		return m_pMainWnd->MessageBox (utf8ToTStr(message), _T("Georges Edit"), MB_YESNO|MB_ICONQUESTION) != IDNO;
+		return m_pMainWnd->MessageBox(nlUtf8ToTStr(message), _T("Georges Edit"), MB_YESNO | MB_ICONQUESTION) != IDNO;
 	else
-		return MessageBox (NULL, utf8ToTStr(message), _T("Georges Edit"), MB_YESNO|MB_ICONQUESTION)  != IDNO;
+		return MessageBox(NULL, nlUtf8ToTStr(message), _T("Georges Edit"), MB_YESNO | MB_ICONQUESTION) != IDNO;
 }
 
 void CGeorgesEditApp::loadPlugins ()
@@ -722,7 +722,7 @@ void CGeorgesEditApp::loadPlugins ()
 	for (i=0; i<PluginsNames.size (); i++)
 	{
 		// Load the dll
-		HINSTANCE hModule = AfxLoadLibrary (utf8ToTStr(PluginsNames[i]));
+		HINSTANCE hModule = AfxLoadLibrary(nlUtf8ToTStr(PluginsNames[i]));
 		if (hModule)
 		{
 			// Get the proc adrdess
@@ -829,10 +829,10 @@ NLGEORGES::IEditDocument *CGeorgesEditApp::createDocument (const char *dfnName,
 			// Set the filename
 			if (strcmp (pathName, "") != 0)
 			{
-				doc->SetPathName (utf8ToTStr(pathName), FALSE );
+				doc->SetPathName (nlUtf8ToTStr(pathName), FALSE );
 
 				// Create the file
-				doc->OnSaveDocument(utf8ToTStr(pathName) );
+				doc->OnSaveDocument(nlUtf8ToTStr(pathName));
 			}
 
 			// Init the frame
@@ -925,7 +925,7 @@ void CGeorgesEditApp::gotoURL (LPCTSTR url)
 
 void CGeorgesEditApp::WinHelp(DWORD dwData, UINT nCmd) 
 {
-	gotoURL(utf8ToTStr(NLMISC::CFile::getPath(ExePath) + "georges_edit.html"));
+	gotoURL(nlUtf8ToTStr(NLMISC::CFile::getPath(ExePath) + "georges_edit.html"));
 }
 
 void CGeorgesEditApp::OnViewRefresh() 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
index 86204d8f7..989afa15b 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.cpp
@@ -102,7 +102,7 @@ bool CMemoryComboBox::getMemory (int slot, std::string &ret)
 		smprintf (strSrc, 512, "%d", slot);
 		TCHAR str[512];
 		LONG size = 512 * sizeof(TCHAR);
-		if (RegQueryValue(hKey, utf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
+		if (RegQueryValue(hKey, nlUtf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
 		{
 			ret = tStrToUtf8(str);
 
@@ -134,12 +134,12 @@ void CMemoryComboBox::scrollDown (int start, int end)
 			smprintf (strSrc, 512, "%d", i-1);
 			TCHAR str[512];
 			LONG size = 512 * sizeof(TCHAR);
-			if (RegQueryValue (hKey, utf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
+			if (RegQueryValue (hKey, nlUtf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
 			{
 				// Set the value
 				char strDst[512];
 				smprintf (strDst, 512, "%d", i);
-				RegSetValue (hKey, utf8ToTStr(strSrc), REG_SZ, str, size);
+				RegSetValue (hKey, nlUtf8ToTStr(strDst), REG_SZ, str, size);
 			} 
 		}
 
@@ -158,7 +158,7 @@ void CMemoryComboBox::pushString (const std::string &str)
 	{
 		// Set the value
 		tstring tstr = utf8ToTStr(str);
-		RegSetValue (hKey, _T("0"), REG_SZ, tstr.c_str (), tstr.size ());
+		RegSetValue (hKey, _T("0"), REG_SZ, tstr.c_str(), (tstr.size() + 1) * sizeof(TCHAR));
 
 		// Close
 		RegCloseKey (hKey);
@@ -444,7 +444,7 @@ void CMemoryComboBox::refreshStrings ()
 	int count = Commands.size();
 	for (i=0; i<StaticStrings.size(); i++)
 	{
-		_ComboBox.InsertString (count, utf8ToTStr(StaticStrings[i]));
+		_ComboBox.InsertString(count, nlUtf8ToTStr(StaticStrings[i]));
 		count++;
 	}
 
@@ -453,7 +453,7 @@ void CMemoryComboBox::refreshStrings ()
 		std::string ret;
 		if (getMemory (i, ret))
 		{
-			_ComboBox.InsertString (count, utf8ToTStr(ret));
+			_ComboBox.InsertString(count, nlUtf8ToTStr(ret));
 			count++;
 		}
 	}
@@ -492,7 +492,7 @@ void CMemoryComboBox::clearCommand ()
 
 void CMemoryComboBox::addLabelCommands (uint i)
 {
-	_ComboBox.InsertString (i, utf8ToTStr(Commands[i].Label));
+	_ComboBox.InsertString(i, nlUtf8ToTStr(Commands[i].Label));
 }
 
 // ***************************************************************************
@@ -683,7 +683,7 @@ BOOL CMemoryComboBox::PreTranslateMessage(MSG* pMsg)
 						if ((!str.IsEmpty()) && (str.Find('.') == -1))
 						{
 							str += _T(".");
-							str += utf8ToTStr(_Extension);
+						    str += nlUtf8ToTStr(_Extension);
 							_ComboBox.SetWindowText (str);
 						}
 					}
diff --git a/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp b/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp
index bcb01031f..ada2b9078 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/reg_shell_ext.cpp
@@ -21,50 +21,53 @@
 using namespace std;
 using namespace NLMISC;
 
-void deleteKey (HKEY hKey, const TCHAR *name)
+void deleteKey(HKEY hKey, const TCHAR *name)
 {
 	HKEY subKey;
-	if (RegOpenKey (hKey, name, &subKey) == ERROR_SUCCESS)
+	if (RegOpenKey(hKey, name, &subKey) == ERROR_SUCCESS)
 	{
 		TCHAR subName[512];
-		while (RegEnumKey (subKey, 0, subName, 512) == ERROR_SUCCESS)
+		while (RegEnumKey(subKey, 0, subName, 512) == ERROR_SUCCESS)
 		{
-			deleteKey (subKey, subName);
+			deleteKey(subKey, subName);
 		}
-		nlverify (RegDeleteKey (hKey, name) == ERROR_SUCCESS);
+		nlverify(RegDeleteKey(hKey, name) == ERROR_SUCCESS);
 	}
 }
 
 // Register an application
-bool RegisterApp (const char *appName, const char *appDescription, const char *icon, int iconIndex)
+bool RegisterApp(const char *appName, const char *appDescription, const char *icon, int iconIndex)
 {
 	// Create the app key
 	HKEY hKey;
-	if (RegCreateKey (HKEY_CLASSES_ROOT, appName, &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(appName), &hKey) == ERROR_SUCCESS)
 	{
 		// Set the description
-		RegSetValue (hKey, "", REG_SZ, appDescription, strlen (appDescription));
- 
+		tstring tAppDescription = utf8ToTStr(appDescription);
+		RegSetValue(hKey, _T(""), REG_SZ, tAppDescription.c_str(), (tAppDescription.size() + 1) * sizeof(TCHAR));
+
 		// Create the icon
 		HKEY hKey2;
-		if (RegCreateKey (hKey, "DefaultIcon", &hKey2) == ERROR_SUCCESS)
+		if (RegCreateKey(hKey, _T("DefaultIcon"), &hKey2) == ERROR_SUCCESS)
 		{
 			// Set the description
 			char tmp[512];
-			smprintf (tmp, 512, "%s,%d", icon, iconIndex);
-			RegSetValue (hKey2, "", REG_SZ, tmp, strlen (tmp));
+			smprintf(tmp, 512, "%s,%d", icon, iconIndex);
+			tstring ttmp = utf8ToTStr(tmp);
+			RegSetValue(hKey2, _T(""), REG_SZ, ttmp.c_str(), (ttmp.size() + 1) * sizeof(TCHAR));
 		}
 
 		// Create the shell/open/command
-		if (RegCreateKey (hKey, "shell", &hKey) == ERROR_SUCCESS)
+		if (RegCreateKey(hKey, _T("shell"), &hKey) == ERROR_SUCCESS)
 		{
-			if (RegCreateKey (hKey, "open", &hKey) == ERROR_SUCCESS)
+			if (RegCreateKey(hKey, _T("open"), &hKey) == ERROR_SUCCESS)
 			{
-				if (RegCreateKey (hKey, "command", &hKey) == ERROR_SUCCESS)
+				if (RegCreateKey(hKey, _T("command"), &hKey) == ERROR_SUCCESS)
 				{
 					// Set the description
-					string tmp = string(icon)+" \"%1\"";
-					RegSetValue (hKey, "", REG_SZ, tmp.c_str(), tmp.size());
+					string tmp = string(icon) + " \"%1\"";
+					tstring ttmp = utf8ToTStr(tmp);
+					RegSetValue(hKey, _T(""), REG_SZ, ttmp.c_str(), (ttmp.size() + 1) * sizeof(TCHAR));
 				}
 			}
 		}
@@ -75,43 +78,44 @@ bool RegisterApp (const char *appName, const char *appDescription, const char *i
 }
 
 // Unregister an application
-bool UnregisterApp (const char *appName)
+bool UnregisterApp(const char *appName)
 {
 	// Delete the app key
-	deleteKey (HKEY_CLASSES_ROOT, appName);
+	deleteKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(appName));
 	return true;
 }
 
 // Unregister an application command
-bool UnregisterAppCommand (const char *appName, const char *command)
+bool UnregisterAppCommand(const char *appName, const char *command)
 {
 	// Create the app key
 	HKEY hKey;
-	if (RegOpenKey (HKEY_CLASSES_ROOT, appName, &hKey) == ERROR_SUCCESS)
+	if (RegOpenKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(appName), &hKey) == ERROR_SUCCESS)
 	{
 		// Create the icon
 		char tmp[512];
-		smprintf (tmp, 512, "shell\\%s", command);
-		deleteKey (hKey, tmp);		
+		smprintf(tmp, 512, "shell\\%s", command);
+		deleteKey(hKey, nlUtf8ToTStr(tmp));
 		return true;
 	}
 	return false;
 }
 
 // Register an application command
-bool RegisterAppCommand (const char *appName, const char *command, const char *app)
+bool RegisterAppCommand(const char *appName, const char *command, const char *app)
 {
 	// Create the app key
 	HKEY hKey;
-	if (RegCreateKey (HKEY_CLASSES_ROOT, appName, &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(appName), &hKey) == ERROR_SUCCESS)
 	{
 		// Create the icon
 		char tmp[512];
-		smprintf (tmp, 512, "shell\\%s\\command", command);
-		if (RegCreateKey (hKey, tmp, &hKey) == ERROR_SUCCESS)
+		smprintf(tmp, 512, "shell\\%s\\command", command);
+		if (RegCreateKey(hKey, nlUtf8ToTStr(tmp), &hKey) == ERROR_SUCCESS)
 		{
 			// Set the description
-			RegSetValue (hKey, "", REG_SZ, app, strlen (app));
+			tstring tapp = utf8ToTStr(app);
+			RegSetValue(hKey, _T(""), REG_SZ, tapp.c_str(), (tapp.size() + 1) * sizeof(TCHAR));
 		}
 		return true;
 	}
@@ -119,41 +123,43 @@ bool RegisterAppCommand (const char *appName, const char *command, const char *a
 }
 
 // Unregister an application DDE command
-bool UnregisterDDECommand (const char *appName, const char *command)
+bool UnregisterDDECommand(const char *appName, const char *command)
 {
 	// Create the app key
 	HKEY hKey;
-	if (RegOpenKey (HKEY_CLASSES_ROOT, appName, &hKey) == ERROR_SUCCESS)
+	if (RegOpenKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(appName), &hKey) == ERROR_SUCCESS)
 	{
 		// Create the icon
 		char tmp[512];
-		smprintf (tmp, 512, "shell\\%s\\ddeexec", command);
-		deleteKey (hKey, tmp);
+		smprintf(tmp, 512, "shell\\%s\\ddeexec", command);
+		deleteKey(hKey, nlUtf8ToTStr(tmp));
 	}
 	return false;
 }
 
 // Register an application DDE command
-bool RegisterDDECommand (const char *appName, const char *command, const char *ddeCommand, const char *application)
+bool RegisterDDECommand(const char *appName, const char *command, const char *ddeCommand, const char *application)
 {
 	// Create the app key
 	HKEY hKey;
-	if (RegCreateKey (HKEY_CLASSES_ROOT, appName, &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(appName), &hKey) == ERROR_SUCCESS)
 	{
 		// Create the icon
 		char tmp[512];
-		smprintf (tmp, 512, "shell\\%s\\ddeexec", command);
-		if (RegCreateKey (hKey, tmp, &hKey) == ERROR_SUCCESS)
+		smprintf(tmp, 512, "shell\\%s\\ddeexec", command);
+		if (RegCreateKey(hKey, nlUtf8ToTStr(tmp), &hKey) == ERROR_SUCCESS)
 		{
 			// Set the description
-			RegSetValue (hKey, "", REG_SZ, ddeCommand, strlen (ddeCommand));
+			tstring tddeCommand = utf8ToTStr(ddeCommand);
+			RegSetValue(hKey, _T(""), REG_SZ, tddeCommand.c_str(), (tddeCommand.size() + 1) * sizeof(TCHAR));
 			HKEY hKey2;
-			if (RegCreateKey (hKey, "application", &hKey2) == ERROR_SUCCESS)
+			if (RegCreateKey(hKey, _T("application"), &hKey2) == ERROR_SUCCESS)
 			{
-				RegSetValue (hKey2, "", REG_SZ, application, strlen (application));
-				if (RegCreateKey (hKey, "topic", &hKey2) == ERROR_SUCCESS)
+				tstring tapplication = utf8ToTStr(application);
+				RegSetValue(hKey2, _T(""), REG_SZ, tapplication.c_str(), (tapplication.size() + 1) * sizeof(TCHAR));
+				if (RegCreateKey(hKey, _T("topic"), &hKey2) == ERROR_SUCCESS)
 				{
-					RegSetValue (hKey2, "", REG_SZ, "system", strlen ("system"));
+					RegSetValue(hKey2, _T(""), REG_SZ, _T("system"), (strlen("system") + 1) * sizeof(TCHAR));
 					return true;
 				}
 			}
@@ -163,28 +169,29 @@ bool RegisterDDECommand (const char *appName, const char *command, const char *d
 }
 
 // Register a file extension
-bool RegisterShellFileExt (const char *ext, const char *appName)
+bool RegisterShellFileExt(const char *ext, const char *appName)
 {
 	// Remove key in explorer registry if exist
 	HKEY hKey;
-	string key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\"+string (ext);
-	deleteKey (HKEY_CURRENT_USER, key.c_str ());
+	string key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + string(ext);
+	deleteKey(HKEY_CURRENT_USER, nlUtf8ToTStr(key));
 
 	// Create the app key
-	if (RegCreateKey (HKEY_CLASSES_ROOT, ext, &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(ext), &hKey) == ERROR_SUCCESS)
 	{
 		// Set the description
-		RegSetValue (hKey, "", REG_SZ, appName, strlen (appName));
+		tstring tAppName = utf8ToTStr(appName);
+		RegSetValue(hKey, _T(""), REG_SZ, tAppName.c_str(), (tAppName.size() + 1) * sizeof(TCHAR));
 		return true;
 	}
 	return false;
 }
 
 // Register a file extension
-bool UnregisterShellFileExt (const char *ext)
+bool UnregisterShellFileExt(const char *ext)
 {
 	// Delete the app key
-	if (RegDeleteKey  (HKEY_CLASSES_ROOT, ext) == ERROR_SUCCESS)
+	if (RegDeleteKey(HKEY_CLASSES_ROOT, nlUtf8ToTStr(ext)) == ERROR_SUCCESS)
 	{
 		return true;
 	}
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/file_dialog_ex.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/file_dialog_ex.cpp
index 47128cdb5..f4d203a19 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/file_dialog_ex.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/file_dialog_ex.cpp
@@ -59,9 +59,9 @@ INT_PTR CFileDialogEx::DoModal ()
 	HKEY hKey;
 	DWORD type = REG_SZ;
 	DWORD size = 512 * sizeof(TCHAR);
-	if (RegCreateKey (HKEY_CURRENT_USER, utf8ToTStr(_RegistryPath), &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey(HKEY_CURRENT_USER, nlUtf8ToTStr(_RegistryPath), &hKey) == ERROR_SUCCESS)
 	{
-		if (RegQueryValueEx (hKey, utf8ToTStr(_FileType), 0, &type, (LPBYTE)path, &size) == ERROR_SUCCESS)
+		if (RegQueryValueEx(hKey, nlUtf8ToTStr(_FileType), 0, &type, (LPBYTE)path, &size) == ERROR_SUCCESS)
 			m_ofn.lpstrInitialDir = path;
 	}
 
@@ -76,9 +76,9 @@ INT_PTR CFileDialogEx::DoModal ()
 		std::string newPath = NLMISC::CFile::getPath (tStrToUtf8(GetPathName()));
 
 		TCHAR buffer[MAX_PATH];
-		_tcscpy_s(buffer, MAX_PATH, utf8ToTStr(newPath));
+		_tcscpy_s(buffer, MAX_PATH, nlUtf8ToTStr(newPath));
 
-		RegSetValueEx (hKey, utf8ToTStr(_FileType), 0, REG_SZ, (LPBYTE)buffer, (_tcslen(buffer) + 1) * sizeof(TCHAR));
+		RegSetValueEx(hKey, nlUtf8ToTStr(_FileType), 0, REG_SZ, (LPBYTE)buffer, (_tcslen(buffer) + 1) * sizeof(TCHAR));
 
 		// Update the path list
 		set<string> oldPath;
@@ -86,7 +86,7 @@ INT_PTR CFileDialogEx::DoModal ()
 		for (i=0; i<PATH_REMEBERED_SIZE; i++)
 		{
 			size = 512;
-			if (RegQueryValueEx (hKey, utf8ToTStr(toString(i)), 0, &type, (LPBYTE)path, &size) == ERROR_SUCCESS)
+			if (RegQueryValueEx(hKey, nlUtf8ToTStr(toString(i)), 0, &type, (LPBYTE)path, &size) == ERROR_SUCCESS)
 				oldPath.insert (tStrToUtf8(path));
 		}
 		oldPath.insert (newPath);
@@ -94,9 +94,9 @@ INT_PTR CFileDialogEx::DoModal ()
 		uint index = 0;
 		while (ite != oldPath.end ())
 		{
-			_tcscpy_s(buffer, MAX_PATH, utf8ToTStr(*ite));
+			_tcscpy_s(buffer, MAX_PATH, nlUtf8ToTStr(*ite));
 
-			RegSetValueEx (hKey, utf8ToTStr(toString(index)), 0, REG_SZ, (LPBYTE)buffer, (_tcslen(buffer) + 1) * sizeof(TCHAR));
+			RegSetValueEx(hKey, nlUtf8ToTStr(toString(index)), 0, REG_SZ, (LPBYTE)buffer, (_tcslen(buffer) + 1) * sizeof(TCHAR));
 			ite++;
 			index++;
 		}
@@ -158,13 +158,13 @@ BOOL CFileDialogEx::OnInitDialog()
 	HKEY hKey;
 	DWORD type = REG_SZ;
 	DWORD size;
-	if (RegCreateKey (HKEY_CURRENT_USER, utf8ToTStr(_RegistryPath), &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey(HKEY_CURRENT_USER, nlUtf8ToTStr(_RegistryPath), &hKey) == ERROR_SUCCESS)
 	{
 		uint i;
 		for (i=0; i<PATH_REMEBERED_SIZE; i++)
 		{
 			size = 512 * sizeof(TCHAR);
-			if (RegQueryValueEx (hKey, utf8ToTStr(toString(i)), 0, &type, (LPBYTE)text, &size) == ERROR_SUCCESS)
+			if (RegQueryValueEx(hKey, nlUtf8ToTStr(toString(i)), 0, &type, (LPBYTE)text, &size) == ERROR_SUCCESS)
 				combo.InsertString (-1, text);
 		}
 		if (m_ofn.lpstrInitialDir)
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/DialogFlags.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/DialogFlags.cpp
index 12c3d9b88..0dbe2849d 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/DialogFlags.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/DialogFlags.cpp
@@ -301,7 +301,7 @@ void CDialogFlags::setCurrentEntityDisplayMode(TEntityDisplayMode edm)
 void CDialogFlags::loadEntityDisplayInfoToRegistry(TEntityDisplayInfoVect &infos, const std::string &regId)
 {
 	HKEY hKey;
-	if (RegOpenKeyEx(HKEY_CURRENT_USER, utf8ToTStr(tStrToUtf8(REGKEY_ENTITY_DISPLAY_INFO) + regId), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+	if (RegOpenKeyEx(HKEY_CURRENT_USER, nlUtf8ToTStr(tStrToUtf8(REGKEY_ENTITY_DISPLAY_INFO) + regId), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
 	{
 		DWORD index  = 0;
 		for(;;)
@@ -338,7 +338,7 @@ void CDialogFlags::loadEntityDisplayInfoToRegistry(TEntityDisplayInfoVect &infos
 void CDialogFlags::saveEntityDisplayInfoToRegistry(const TEntityDisplayInfoVect &infos, const std::string &regId)
 {
 	HKEY hKey;
-	if (RegCreateKeyEx(HKEY_CURRENT_USER, utf8ToTStr(tStrToUtf8(REGKEY_ENTITY_DISPLAY_INFO) + regId), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
+	if (RegCreateKeyEx(HKEY_CURRENT_USER, nlUtf8ToTStr(tStrToUtf8(REGKEY_ENTITY_DISPLAY_INFO) + regId), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
 	{
 		for(uint k = 0; k < infos.size(); ++k)
 		{
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/memory_combo_box.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/memory_combo_box.cpp
index 09756ddbf..5f50ca065 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/memory_combo_box.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/memory_combo_box.cpp
@@ -95,14 +95,14 @@ bool CMemoryComboBox::getMemory (int slot, std::string &ret)
 {
 	// Open the key
 	HKEY hKey;
-	if (RegOpenKey (HKEY_CURRENT_USER, utf8ToTStr(RegisterAdress), &hKey) == ERROR_SUCCESS)
+	if (RegOpenKey(HKEY_CURRENT_USER, nlUtf8ToTStr(RegisterAdress), &hKey) == ERROR_SUCCESS)
 	{
 		// Get the value
 		char strSrc[512];
 		smprintf (strSrc, 512, "%d", slot);
 		TCHAR str[512];
 		long size = 512*sizeof(TCHAR);
-		if (RegQueryValue (hKey, utf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
+		if (RegQueryValue(hKey, nlUtf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
 		{
 			ret = tStrToUtf8(str);
 
@@ -124,7 +124,7 @@ void CMemoryComboBox::scrollDown (int start, int end)
 {
 	// Open the key
 	HKEY hKey;
-	if (RegCreateKey (HKEY_CURRENT_USER, utf8ToTStr(RegisterAdress), &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey (HKEY_CURRENT_USER, nlUtf8ToTStr(RegisterAdress), &hKey) == ERROR_SUCCESS)
 	{
 		// Scroll down the list
 		for (int i=end-1; i>start; i--)
@@ -134,12 +134,12 @@ void CMemoryComboBox::scrollDown (int start, int end)
 			smprintf (strSrc, 512, "%d", i-1);
 			TCHAR str[512];
 			long size = 512 * sizeof(TCHAR);
-			if (RegQueryValue (hKey, utf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
+			if (RegQueryValue(hKey, nlUtf8ToTStr(strSrc), str, &size) == ERROR_SUCCESS)
 			{
 				// Set the value
 				char strDst[512];
 				smprintf (strDst, 512, "%d", i);
-				RegSetValue (hKey, utf8ToTStr(strDst), REG_SZ, str, size);
+				RegSetValue(hKey, nlUtf8ToTStr(strDst), REG_SZ, str, size);
 			} 
 		}
 
@@ -154,10 +154,10 @@ void CMemoryComboBox::writeStringInRegistry (const std::string &str)
 {
 	// Open the key
 	HKEY hKey;
-	if (RegCreateKey (HKEY_CURRENT_USER, utf8ToTStr(RegisterAdress), &hKey) == ERROR_SUCCESS)
+	if (RegCreateKey(HKEY_CURRENT_USER, nlUtf8ToTStr(RegisterAdress), &hKey) == ERROR_SUCCESS)
 	{
 		// Set the value
-		RegSetValue (hKey, _T("0"), REG_SZ, utf8ToTStr(str), str.size ());
+		RegSetValue(hKey, _T("0"), REG_SZ, nlUtf8ToTStr(str), str.size());
 
 		// Close
 		RegCloseKey (hKey);
@@ -428,7 +428,7 @@ void CMemoryComboBox::pushString (const std::string &str)
 			if (i == (int)(itemCount+Commands.size()+ StaticStrings.size()))
 			{
 				// Insert the sting
-				_ComboBox.InsertString (Commands.size()+ StaticStrings.size(), utf8ToTStr(str));
+				_ComboBox.InsertString(Commands.size() + StaticStrings.size(), nlUtf8ToTStr(str));
 			}
 		}
 	}
@@ -449,7 +449,7 @@ void CMemoryComboBox::refreshStrings ()
 	int count = Commands.size();
 	for (i=0; i<StaticStrings.size(); i++)
 	{
-		_ComboBox.InsertString (count, utf8ToTStr(StaticStrings[i]));
+		_ComboBox.InsertString(count, nlUtf8ToTStr(StaticStrings[i]));
 		count++;
 	}
 
@@ -458,7 +458,7 @@ void CMemoryComboBox::refreshStrings ()
 		std::string ret;
 		if (getMemory (i, ret))
 		{
-			_ComboBox.InsertString (count, utf8ToTStr(ret));
+			_ComboBox.InsertString(count, nlUtf8ToTStr(ret));
 			count++;
 		}
 	}
@@ -497,7 +497,7 @@ void CMemoryComboBox::clearCommand ()
 
 void CMemoryComboBox::addLabelCommands (uint i)
 {
-	_ComboBox.InsertString (i, utf8ToTStr(Commands[i].Label));
+	_ComboBox.InsertString(i, nlUtf8ToTStr(Commands[i].Label));
 }
 
 // ***************************************************************************
@@ -688,7 +688,7 @@ BOOL CMemoryComboBox::PreTranslateMessage(MSG* pMsg)
 						if ((!str2.empty ()) && (str2.find ('.') == string::npos))
 						{
 							str2 += "." + _Extension;
-							_ComboBox.SetWindowText (utf8ToTStr(str2));
+						    _ComboBox.SetWindowText(nlUtf8ToTStr(str2));
 						}
 					}
 
@@ -739,7 +739,7 @@ CString CMemoryComboBox::getCurrString() const
 // ***************************************************************************
 void CMemoryComboBox::setCurSel(const std::string &value)
 {
-	int index = _ComboBox.FindStringExact(0, utf8ToTStr(value));
+	int index = _ComboBox.FindStringExact(0, nlUtf8ToTStr(value));
 	if (index != CB_ERR)
 	{
 		_ComboBox.SetCurSel(index);

From cf370eb03c2904db00d29e7a9acfc3e76bdd25d7 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 06:28:49 +0800
Subject: [PATCH 44/75] Cleaning up unicode conversion

---
 .../3d/driver/opengl/driver_opengl_window.cpp |  2 +-
 code/nel/src/sound/driver/sound_driver.cpp    |  2 +-
 .../3d/object_viewer/animation_set_dlg.cpp    | 18 +++---
 .../nel/tools/3d/object_viewer/attrib_dlg.cpp |  2 +-
 .../tools/3d/object_viewer/choose_name.cpp    |  2 +-
 .../tools/3d/object_viewer/choose_pool_id.cpp |  8 +--
 .../3d/object_viewer/create_file_dlg.cpp      |  6 +-
 .../tools/3d/object_viewer/direction_attr.cpp |  2 +-
 code/nel/tools/3d/object_viewer/edit_ex.cpp   |  2 +-
 .../3d/object_viewer/edit_morph_mesh_dlg.cpp  | 10 ++--
 .../tools/3d/object_viewer/edit_ps_sound.cpp  |  4 +-
 .../tools/3d/object_viewer/editable_range.h   |  6 +-
 .../tools/3d/object_viewer/emitter_dlg.cpp    |  2 +-
 .../3d/object_viewer/lb_extern_id_dlg.cpp     |  2 +-
 .../object_viewer/located_bindable_dialog.cpp |  2 +-
 .../3d/object_viewer/located_properties.cpp   |  2 +-
 .../3d/object_viewer/located_target_dlg.cpp   |  8 +--
 .../nel/tools/3d/object_viewer/main_frame.cpp |  6 +-
 code/nel/tools/3d/object_viewer/mesh_dlg.cpp  |  8 +--
 .../tools/3d/object_viewer/multi_tex_dlg.cpp  | 18 +++---
 .../tools/3d/object_viewer/object_viewer.cpp  | 36 ++++++------
 .../tools/3d/object_viewer/particle_dlg.cpp   | 12 ++--
 .../3d/object_viewer/particle_tree_ctrl.cpp   | 56 +++++++++----------
 .../3d/object_viewer/particle_workspace.cpp   |  4 +-
 .../nel/tools/3d/object_viewer/pick_sound.cpp |  8 +--
 .../precomputed_rotations_dlg.cpp             |  6 +-
 .../tools/3d/object_viewer/ps_mover_dlg.cpp   |  8 +--
 .../3d/object_viewer/scheme_bank_dlg.cpp      | 16 +++---
 .../tools/3d/object_viewer/select_string.cpp  |  4 +-
 .../3d/object_viewer/skeleton_scale_dlg.cpp   | 20 +++----
 code/nel/tools/3d/object_viewer/slot_dlg.cpp  |  2 +-
 .../3d/object_viewer/snapshot_tool_dlg.cpp    |  4 +-
 .../tools/3d/object_viewer/sound_anim_dlg.cpp |  4 +-
 .../3d/object_viewer/sound_anim_view.cpp      |  4 +-
 .../start_stop_particle_system.cpp            | 10 ++--
 .../3d/object_viewer/texture_chooser.cpp      |  8 +--
 .../3d/object_viewer/vegetable_copy_dlg.cpp   |  2 +-
 .../object_viewer/vegetable_density_page.cpp  | 12 ++--
 .../tools/3d/object_viewer/vegetable_dlg.cpp  | 24 ++++----
 .../3d/object_viewer/vegetable_edit_tools.cpp |  2 +-
 .../vegetable_noise_value_dlg.cpp             |  4 +-
 .../3d/object_viewer/vegetable_select_dlg.cpp |  2 +-
 .../3d/object_viewer/vegetable_wind_dlg.cpp   | 12 ++--
 .../3d/object_viewer/water_pool_editor.cpp    | 18 +++---
 code/nel/tools/3d/tile_edit/Browse.cpp        |  6 +-
 .../3d/tile_edit/SelectionTerritoire.cpp      | 30 +++++-----
 code/nel/tools/3d/tile_edit/View.cpp          | 46 +++++++--------
 .../tools/3d/tile_edit/choose_veget_set.cpp   |  6 +-
 48 files changed, 239 insertions(+), 239 deletions(-)

diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp
index 3d1803a2a..2e0f2e7a5 100644
--- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp
+++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp
@@ -2644,7 +2644,7 @@ IDriver::TMessageBoxId CDriverGL::systemMessageBox (const char* message, const c
 {
 	H_AUTO_OGL(CDriverGL_systemMessageBox)
 #ifdef NL_OS_WINDOWS
-	switch (::MessageBoxW (NULL, utf8ToWide(message), utf8ToWide(title), ((type==retryCancelType)?MB_RETRYCANCEL:
+	switch (::MessageBoxW(NULL, nlUtf8ToWide(message), nlUtf8ToWide(title), ((type == retryCancelType) ? MB_RETRYCANCEL :
 										(type==yesNoCancelType)?MB_YESNOCANCEL:
 										(type==okCancelType)?MB_OKCANCEL:
 										(type==abortRetryIgnoreType)?MB_ABORTRETRYIGNORE:
diff --git a/code/nel/src/sound/driver/sound_driver.cpp b/code/nel/src/sound/driver/sound_driver.cpp
index 6e1ada902..7eeaf9f57 100644
--- a/code/nel/src/sound/driver/sound_driver.cpp
+++ b/code/nel/src/sound/driver/sound_driver.cpp
@@ -226,7 +226,7 @@ ISoundDriver *ISoundDriver::createDriver(IStringMapperProvider *stringMapper, TD
 	 */
 #ifdef NL_OS_WINDOWS
 	wchar_t buffer[1024], *ptr;
-	uint len = SearchPathW (NULL, utf8ToWide(dllName), NULL, 1023, buffer, &ptr);
+	uint len = SearchPathW (NULL, nlUtf8ToWide(dllName), NULL, 1023, buffer, &ptr);
 	if( len )
 		nlinfo ("Using the library '%s' that is in the directory: '%s'", dllName.c_str(), wideToUtf8(buffer).c_str());
 #endif
diff --git a/code/nel/tools/3d/object_viewer/animation_set_dlg.cpp b/code/nel/tools/3d/object_viewer/animation_set_dlg.cpp
index a815a83a6..743bb6b32 100644
--- a/code/nel/tools/3d/object_viewer/animation_set_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/animation_set_dlg.cpp
@@ -158,7 +158,7 @@ void CAnimationSetDlg::OnAddAnimation ()
 			}
 			catch (const Exception& e)
 			{
-				MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox (nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
 			}
 		}
 	}
@@ -199,7 +199,7 @@ void CAnimationSetDlg::OnAddSkelWt()
 			}
 			catch (const Exception& e)
 			{
-				MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			}
 		}
 	}
@@ -234,7 +234,7 @@ void CAnimationSetDlg::refresh (BOOL update)
 		for (i=0; i<_ObjView->getNumInstance (); i++)
 		{
 			std::string name = NLMISC::CFile::getFilenameWithoutExtension(_ObjView->getInstance(i)->Saved.ShapeFilename);
-			EditedObject.InsertString (-1, utf8ToTStr(name));
+			EditedObject.InsertString(-1, nlUtf8ToTStr(name));
 		}
 
 		// Get edited object
@@ -268,7 +268,7 @@ void CAnimationSetDlg::refresh (BOOL update)
 				CAnimation *anim = object->AnimationSet.getAnimation (object->AnimationSet.getAnimationIdByName (name));
 
 				// Insert an intem
-				HTREEITEM item=Tree.InsertItem(utf8ToTStr(name));
+				HTREEITEM item = Tree.InsertItem(nlUtf8ToTStr(name));
 				Tree.SetItemData (item, i);
 				nlassert (item!=NULL);
 
@@ -279,7 +279,7 @@ void CAnimationSetDlg::refresh (BOOL update)
 				while (ite!=setString.end())
 				{
 					// Add this string
-					HTREEITEM newItem = Tree.InsertItem (utf8ToTStr(*ite), item);
+					HTREEITEM newItem = Tree.InsertItem(nlUtf8ToTStr(*ite), item);
 					Tree.SetItemData (newItem, 0xffffffff);
 
 					// Get the track
@@ -303,7 +303,7 @@ void CAnimationSetDlg::refresh (BOOL update)
 						name = toString("%s (%f - %f)", typeid(*track).name(), track->getBeginTime(), track->getEndTime());
 					}
 
-					HTREEITEM keyItem = Tree.InsertItem(utf8ToTStr(name), newItem);
+					HTREEITEM keyItem = Tree.InsertItem(nlUtf8ToTStr(name), newItem);
 					Tree.SetItemData(keyItem, 0xffffffff);
 
 					ite++;
@@ -320,7 +320,7 @@ void CAnimationSetDlg::refresh (BOOL update)
 				CSkeletonWeight *swt = object->AnimationSet.getSkeletonWeight(object->AnimationSet.getSkeletonWeightIdByName(name));
 
 				// Insert an intem
-				HTREEITEM item=SkelTree.InsertItem(utf8ToTStr(name));
+				HTREEITEM item = SkelTree.InsertItem(nlUtf8ToTStr(name));
 				nlassert (item!=NULL);
 
 				// Get number of node in this skeleton weight
@@ -332,7 +332,7 @@ void CAnimationSetDlg::refresh (BOOL update)
 					std::string percent = toString("%s (%f%%)", swt->getNodeName(n).c_str(), swt->getNodeWeight(n)*100);
 
 					// Add this string
-					SkelTree.InsertItem (utf8ToTStr(percent), item);
+					SkelTree.InsertItem(nlUtf8ToTStr(percent), item);
 				}
 			}
 
@@ -340,7 +340,7 @@ void CAnimationSetDlg::refresh (BOOL update)
 			for (i=0; i<object->Saved.PlayList.size(); i++)
 			{
 				// Insert an intem
-				int item=PlayList.InsertString (-1, utf8ToTStr(object->Saved.PlayList[i]));
+				int item = PlayList.InsertString(-1, nlUtf8ToTStr(object->Saved.PlayList[i]));
 				nlassert (item!=LB_ERR);
 			}
 		}
diff --git a/code/nel/tools/3d/object_viewer/attrib_dlg.cpp b/code/nel/tools/3d/object_viewer/attrib_dlg.cpp
index 674e7f307..93ac94209 100644
--- a/code/nel/tools/3d/object_viewer/attrib_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/attrib_dlg.cpp
@@ -355,7 +355,7 @@ void CAttribDlg::init(HBITMAP bitmap, sint x, sint y, CWnd *pParent)
 	for (uint k = 0; k < getNumScheme(); ++k)
 	{	
 
-		m_Scheme.InsertString(k, utf8ToTStr(getSchemeName(k)));
+		m_Scheme.InsertString(k, nlUtf8ToTStr(getSchemeName(k)));
 
 	}
 
diff --git a/code/nel/tools/3d/object_viewer/choose_name.cpp b/code/nel/tools/3d/object_viewer/choose_name.cpp
index 91dbf8d40..4f26140a4 100644
--- a/code/nel/tools/3d/object_viewer/choose_name.cpp
+++ b/code/nel/tools/3d/object_viewer/choose_name.cpp
@@ -33,7 +33,7 @@ CChooseName::CChooseName(const CString &initialName, CWnd* pParent /*=NULL*/)
 
 std::string CChooseName::getName()
 {
-	return tStrToUtf8(m_Name);
+	return NLMISC::tStrToUtf8(m_Name);
 }
 
 void CChooseName::DoDataExchange(CDataExchange* pDX)
diff --git a/code/nel/tools/3d/object_viewer/choose_pool_id.cpp b/code/nel/tools/3d/object_viewer/choose_pool_id.cpp
index 3653e72d1..2423bc70a 100644
--- a/code/nel/tools/3d/object_viewer/choose_pool_id.cpp
+++ b/code/nel/tools/3d/object_viewer/choose_pool_id.cpp
@@ -53,10 +53,10 @@ void CChoosePoolID::OnOK()
 	CString val;
 	GetDlgItem(IDC_POOL_ID)->GetWindowText(val);
 
-	if (NLMISC::fromString(tStrToUtf8(val), PoolID))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(val), PoolID))
 	{
 		GetDlgItem(IDC_POOL_NAME)->GetWindowText(val);
-		Name = tStrToUtf8(val);
+		Name = NLMISC::tStrToUtf8(val);
 		CDialog::OnOK();
 	}
 	else
@@ -71,8 +71,8 @@ BOOL CChoosePoolID::OnInitDialog()
 
 	std::string val = NLMISC::toString(PoolID);
 
-	GetDlgItem(IDC_POOL_ID)->SetWindowText(utf8ToTStr(val));
-	GetDlgItem(IDC_POOL_NAME)->SetWindowText(utf8ToTStr(Name));
+	GetDlgItem(IDC_POOL_ID)->SetWindowText(nlUtf8ToTStr(val));
+	GetDlgItem(IDC_POOL_NAME)->SetWindowText(nlUtf8ToTStr(Name));
 
 	if (_FreezeID)
 	{
diff --git a/code/nel/tools/3d/object_viewer/create_file_dlg.cpp b/code/nel/tools/3d/object_viewer/create_file_dlg.cpp
index 64a404f88..28b058bfb 100644
--- a/code/nel/tools/3d/object_viewer/create_file_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/create_file_dlg.cpp
@@ -72,7 +72,7 @@ BOOL CCreateFileDlg::OnInitDialog()
 {
 	CDialog::OnInitDialog();	
 	SetWindowText((LPCTSTR) _Title);
-	GetDlgItem(IDC_LOCATION)->SetWindowText(utf8ToTStr(_DefaultBasePath));
+	GetDlgItem(IDC_LOCATION)->SetWindowText(nlUtf8ToTStr(_DefaultBasePath));
 	if (!_DefaultBasePath.empty())
 	{
 		GetDlgItem(IDC_FILENAME)->SetFocus();
@@ -90,10 +90,10 @@ void CCreateFileDlg::OnOK()
 {
 	CString filename;
 	GetDlgItem(IDC_FILENAME)->GetWindowText(filename);
-	_Filename = tStrToUtf8(filename);
+	_Filename = NLMISC::tStrToUtf8(filename);
 	CString location;
 	GetDlgItem(IDC_LOCATION)->GetWindowText(location);
-	_Path = tStrToUtf8(location);
+	_Path = NLMISC::tStrToUtf8(location);
 	if (_Path.empty())
 	{
 		localizedMessageBox(*this, IDS_EMPTY_PATH, IDS_ERROR, MB_ICONEXCLAMATION);
diff --git a/code/nel/tools/3d/object_viewer/direction_attr.cpp b/code/nel/tools/3d/object_viewer/direction_attr.cpp
index 047457390..6f422f97c 100644
--- a/code/nel/tools/3d/object_viewer/direction_attr.cpp
+++ b/code/nel/tools/3d/object_viewer/direction_attr.cpp
@@ -173,7 +173,7 @@ void CDirectionAttr::OnDestroy()
 void CDirectionAttr::OnGlobalDirection() 
 {
 	nlassert(_DirectionWrapper);
-	CChooseName chooseName(utf8ToTStr(_DirectionWrapper->getGlobalVectorValueName()));
+	CChooseName chooseName(nlUtf8ToTStr(_DirectionWrapper->getGlobalVectorValueName()));
 
 	if (chooseName.DoModal() == IDOK)
 	{
diff --git a/code/nel/tools/3d/object_viewer/edit_ex.cpp b/code/nel/tools/3d/object_viewer/edit_ex.cpp
index 97df943f2..7bf13c3e3 100644
--- a/code/nel/tools/3d/object_viewer/edit_ex.cpp
+++ b/code/nel/tools/3d/object_viewer/edit_ex.cpp
@@ -76,7 +76,7 @@ std::string CEditEx::getString() const
 {
 	TCHAR buf[128];
 	GetWindowText(buf, sizeof(buf));
-	return tStrToUtf8(buf);
+	return NLMISC::tStrToUtf8(buf);
 }
 
 void		CEditEx::setSInt(sint value)
diff --git a/code/nel/tools/3d/object_viewer/edit_morph_mesh_dlg.cpp b/code/nel/tools/3d/object_viewer/edit_morph_mesh_dlg.cpp
index 0c7def7e9..43c80fb80 100644
--- a/code/nel/tools/3d/object_viewer/edit_morph_mesh_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/edit_morph_mesh_dlg.cpp
@@ -89,7 +89,7 @@ bool CEditMorphMeshDlg::getShapeNameFromDlg(std::string &name)
 		NLMISC::CPath::addSearchPath (NLMISC::CFile::getPath(tStrToUtf8(fd.GetPathName()));
 		*/
 
-		name = tStrToUtf8(fd.GetPathName());
+		name = NLMISC::tStrToUtf8(fd.GetPathName());
 		
 		return true;
 	}
@@ -123,7 +123,7 @@ void CEditMorphMeshDlg::OnAdd()
 		_CM->setShapes(&shapeNames[0], (uint)shapeNames.size());
 		std::vector<sint> numVerts;
 		_CM->getShapeNumVerts(numVerts);		
-		m_MeshList.AddString(utf8ToTStr(getShapeDescStr(index, numVerts[index])));
+		m_MeshList.AddString(nlUtf8ToTStr(getShapeDescStr(index, numVerts[index])));
 		GetDlgItem(IDC_REMOVE)->EnableWindow(TRUE);
 	}
 	touchPSState();
@@ -253,7 +253,7 @@ void CEditMorphMeshDlg::updateMeshList()
 	m_MeshList.ResetContent();
 	for (uint k = 0; k < _CM->getNumShapes(); ++k)
 	{	
-		m_MeshList.AddString(utf8ToTStr(getShapeDescStr(k, numVerts[k])));
+		m_MeshList.AddString(nlUtf8ToTStr(getShapeDescStr(k, numVerts[k])));
 	}
 	m_MeshList.SetCurSel(0);
 	updateValidFlag();
@@ -310,12 +310,12 @@ std::string CEditMorphMeshDlg::getShapeDescStr(uint shapeIndex, sint numVerts) c
 	{	
 		CString verts;
 		verts.LoadString(IDS_VERTICES);
-		std::string msg = _CM->getShape(shapeIndex) + " (" + NLMISC::toString(numVerts) + " " + tStrToUtf8(verts) + ")";
+		std::string msg = _CM->getShape(shapeIndex) + " (" + NLMISC::toString(numVerts) + " " + NLMISC::tStrToUtf8(verts) + ")";
 		return msg;
 	}
 	else
 	{		
-		std::string result =  _CM->getShape(shapeIndex) + " (" + tStrToUtf8(CMeshDlg::getShapeErrorString(numVerts)) + ")";
+		std::string result = _CM->getShape(shapeIndex) + " (" + NLMISC::tStrToUtf8(CMeshDlg::getShapeErrorString(numVerts)) + ")";
 		return result;
 	}
 }
diff --git a/code/nel/tools/3d/object_viewer/edit_ps_sound.cpp b/code/nel/tools/3d/object_viewer/edit_ps_sound.cpp
index 40406c2fa..d74c1fdf8 100644
--- a/code/nel/tools/3d/object_viewer/edit_ps_sound.cpp
+++ b/code/nel/tools/3d/object_viewer/edit_ps_sound.cpp
@@ -195,7 +195,7 @@ void CEditPSSound::OnChangeSoundName()
 {
 	nlassert(_Sound);
 	UpdateData();
-	_Sound->setSoundName(NLMISC::CSheetId(tStrToUtf8(m_SoundName), "sound"));	
+	_Sound->setSoundName(NLMISC::CSheetId(NLMISC::tStrToUtf8(m_SoundName), "sound"));	
 	 updateModifiedFlag();
 }
 
@@ -209,7 +209,7 @@ void CEditPSSound::OnSpawn()
 // play the currently selected sound
 void CEditPSSound::OnPlaySound() 
 {
-	CSoundSystem::play(tStrToUtf8(m_SoundName));
+	CSoundSystem::play(NLMISC::tStrToUtf8(m_SoundName));
 }
 
 void CEditPSSound::OnMute() 
diff --git a/code/nel/tools/3d/object_viewer/editable_range.h b/code/nel/tools/3d/object_viewer/editable_range.h
index 5a4b6263c..1ba763cbb 100644
--- a/code/nel/tools/3d/object_viewer/editable_range.h
+++ b/code/nel/tools/3d/object_viewer/editable_range.h
@@ -317,7 +317,7 @@ inline void CEditableRangeT<float>::value2CString(float value, CString &dest)
 
 inline const TCHAR *CEditableRangeT<float>::string2value(const CString &value, float &result)
 {			
-	if (NLMISC::fromString(tStrToUtf8(value), result))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(value), result))
 	{			
 		return NULL;
 	}
@@ -344,7 +344,7 @@ inline void CEditableRangeT<uint32>::value2CString(uint32 value, CString &dest)
 inline const TCHAR *CEditableRangeT<uint32>::string2value(const CString &value, uint32 &result)
 {			
 	sint32 tmp;
-	if (NLMISC::fromString(tStrToUtf8(value), tmp))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(value), tmp))
 	{
 		if (value.Find(_T("-")) > -1)
 		{
@@ -380,7 +380,7 @@ inline void CEditableRangeT<sint32>::value2CString(sint32 value, CString &dest)
 inline const TCHAR *CEditableRangeT<sint32>::string2value(const CString &value, sint32 &result)
 {			
 	sint32 tmp;
-	if (NLMISC::fromString(tStrToUtf8(value), tmp))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(value), tmp))
 	{				
 		result = tmp;
 		return NULL;				
diff --git a/code/nel/tools/3d/object_viewer/emitter_dlg.cpp b/code/nel/tools/3d/object_viewer/emitter_dlg.cpp
index e4864cfe6..df67f68b1 100644
--- a/code/nel/tools/3d/object_viewer/emitter_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/emitter_dlg.cpp
@@ -85,7 +85,7 @@ void CEmitterDlg::initEmittedType()
 		NL3D::CPSLocated *loc = dynamic_cast<NL3D::CPSLocated *>(ps->getProcess(k));
 		if (loc) // is this a located
 		{
-			m_EmittedTypeCtrl.AddString(utf8ToTStr(loc->getName()));
+			m_EmittedTypeCtrl.AddString(nlUtf8ToTStr(loc->getName()));
 			_LocatedList.push_back(loc);			
 			if (loc == _Emitter->getEmittedType())
 			{
diff --git a/code/nel/tools/3d/object_viewer/lb_extern_id_dlg.cpp b/code/nel/tools/3d/object_viewer/lb_extern_id_dlg.cpp
index 9ea2d51a9..9b0432a9b 100644
--- a/code/nel/tools/3d/object_viewer/lb_extern_id_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/lb_extern_id_dlg.cpp
@@ -119,7 +119,7 @@ void CLBExternIDDlg::OnChangeIdValue()
 	TCHAR buf[6];
 	::memset(buf, 0, 6);
 	GetDlgItem(IDC_ID_VALUE)->GetWindowText(buf, 6);
-	_ID = StringToID(tStrToUtf8(buf).c_str());
+	_ID = StringToID(NLMISC::tStrToUtf8(buf).c_str());
 	if (_ID)
 	{
 		GetDlgItem(IDOK)->EnableWindow(TRUE);
diff --git a/code/nel/tools/3d/object_viewer/located_bindable_dialog.cpp b/code/nel/tools/3d/object_viewer/located_bindable_dialog.cpp
index 2242c0684..98ad0794b 100644
--- a/code/nel/tools/3d/object_viewer/located_bindable_dialog.cpp
+++ b/code/nel/tools/3d/object_viewer/located_bindable_dialog.cpp
@@ -114,7 +114,7 @@ void CLocatedBindableDialog::init(CParticleDlg* pParent)
 		// z-test
 		((CButton *) GetDlgItem(IDC_ZTEST))->SetCheck(material->isZTestEnabled() ? BST_CHECKED : BST_UNCHECKED);
 		// z-bias
-		GetDlgItem(IDC_ZBIAS)->SetWindowText(utf8ToTStr(NLMISC::toString("%.2f", -material->getZBias())));
+		GetDlgItem(IDC_ZBIAS)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", -material->getZBias())));
 	}
 	else
 	{
diff --git a/code/nel/tools/3d/object_viewer/located_properties.cpp b/code/nel/tools/3d/object_viewer/located_properties.cpp
index b270e9d7f..ad77243bc 100644
--- a/code/nel/tools/3d/object_viewer/located_properties.cpp
+++ b/code/nel/tools/3d/object_viewer/located_properties.cpp
@@ -322,7 +322,7 @@ void CLocatedProperties::goPostRender()
 		_MaxNbParticles->update();
 	}
 	// in all cases, show the current number of particles being used
-	GetDlgItem(IDC_CURR_NUM_PARTS)->SetWindowText(utf8ToTStr(NLMISC::toString(_Located->getSize())));
+	GetDlgItem(IDC_CURR_NUM_PARTS)->SetWindowText(nlUtf8ToTStr(NLMISC::toString(_Located->getSize())));
 }
 
 //****************************************************************************************************************
diff --git a/code/nel/tools/3d/object_viewer/located_target_dlg.cpp b/code/nel/tools/3d/object_viewer/located_target_dlg.cpp
index 03fcb226c..4de7dbe37 100644
--- a/code/nel/tools/3d/object_viewer/located_target_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/located_target_dlg.cpp
@@ -112,7 +112,7 @@ void CLocatedTargetDlg::OnAddTarget()
 		nlassert(loc);
 		_LBTarget->attachTarget(loc);
 		m_AvailableTargets.DeleteString(indexs[k] - k);
-		int l = m_Targets.AddString(utf8ToTStr(loc->getName()));
+		int l = m_Targets.AddString(nlUtf8ToTStr(loc->getName()));
 		m_Targets.SetItemData(l, (DWORD_PTR) loc);
 	}	
 	UpdateData(FALSE);
@@ -135,7 +135,7 @@ void CLocatedTargetDlg::OnRemoveTarget()
 		nlassert(loc);
 		_LBTarget->detachTarget(loc);
 		m_Targets.DeleteString(indexs[k] - k);
-		int l = m_AvailableTargets.AddString(utf8ToTStr(loc->getName()));
+		int l = m_AvailableTargets.AddString(nlUtf8ToTStr(loc->getName()));
 	
 		m_AvailableTargets.SetItemData(l, (DWORD_PTR) loc);
 	}
@@ -159,7 +159,7 @@ BOOL CLocatedTargetDlg::OnInitDialog()
 	// fill the box thta tells us what the target are
 	for(k = 0; k < nbTarg; ++k)
 	{
-		m_Targets.AddString(utf8ToTStr(_LBTarget->getTarget(k)->getName()));
+		m_Targets.AddString(nlUtf8ToTStr(_LBTarget->getTarget(k)->getName()));
 		m_Targets.SetItemData(k, (DWORD_PTR) _LBTarget->getTarget(k));
 		targetSet.insert(_LBTarget->getTarget(k));
 	};
@@ -179,7 +179,7 @@ BOOL CLocatedTargetDlg::OnInitDialog()
 		{
 			if (targetSet.find(loc) == targetSet.end())
 			{
-				int l = m_AvailableTargets.AddString(utf8ToTStr(loc->getName()));
+				int l = m_AvailableTargets.AddString(nlUtf8ToTStr(loc->getName()));
 				m_AvailableTargets.SetItemData(l, (DWORD_PTR) loc);
 			}
 		}
diff --git a/code/nel/tools/3d/object_viewer/main_frame.cpp b/code/nel/tools/3d/object_viewer/main_frame.cpp
index aa24efa36..7e3b81486 100644
--- a/code/nel/tools/3d/object_viewer/main_frame.cpp
+++ b/code/nel/tools/3d/object_viewer/main_frame.cpp
@@ -592,7 +592,7 @@ void CMainFrame::OnFileLoadconfig()
 			}
 			catch (const Exception& e)
 			{
-				MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			}
 		}
 		else
@@ -764,7 +764,7 @@ void CMainFrame::OnFileSaveconfig()
 			}
 			catch (const Exception& e)
 			{
-				MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			}
 		}
 		else
@@ -1443,7 +1443,7 @@ void CMainFrame::OnUpdateSceneCamera(CCmdUI* pCmdUI)
 		CInstanceInfo *instance = ObjView->getInstance (ObjView->getCameraInstance (pCmdUI->m_nID - ID_SCENE_CAMERA_FIRST));
 		nlassert (instance->Camera);
 		std::string text = NLMISC::toString("Camera %s", instance->Saved.ShapeFilename.c_str());
-		pCmdUI->SetText(utf8ToTStr(text));
+		pCmdUI->SetText(nlUtf8ToTStr(text));
 	}
 	else
 	{
diff --git a/code/nel/tools/3d/object_viewer/mesh_dlg.cpp b/code/nel/tools/3d/object_viewer/mesh_dlg.cpp
index a35b7fe71..b83552ab0 100644
--- a/code/nel/tools/3d/object_viewer/mesh_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/mesh_dlg.cpp
@@ -94,7 +94,7 @@ void CMeshDlg::OnBrowseShape()
 	if (fd.DoModal() == IDOK)
 	{
 		// Add to the path
-		std::string fullPath = tStrToUtf8(fd.GetPathName());
+		std::string fullPath = NLMISC::tStrToUtf8(fd.GetPathName());
 		std::string fname = NLMISC::CFile::getFilenameWithoutExtension(fullPath);
 		std::string ext = NLMISC::CFile::getExtension(fullPath);
 
@@ -104,12 +104,12 @@ void CMeshDlg::OnBrowseShape()
 		try
 		{		
 			_ShapeParticle->setShape(fname + "." + ext);		
-			m_ShapeName = utf8ToTStr(fname + "." + ext);
+			m_ShapeName = nlUtf8ToTStr(fname + "." + ext);
 			touchPSState();			
 		}
 		catch (const NLMISC::Exception &e)
 		{
-			MessageBox(utf8ToTStr(e.what()), _T("shape loading error"));
+			MessageBox(nlUtf8ToTStr(e.what()), _T("shape loading error"));
 		}		
 
 		updateMeshErrorString();
@@ -159,7 +159,7 @@ void CMeshDlg::updateForMorph()
 		GetDlgItem(IDC_SHAPE_NAME)->EnableWindow(!enable);
 		if (!enable)
 		{
-			m_ShapeName = utf8ToTStr(cm->getShape());
+			m_ShapeName = nlUtf8ToTStr(cm->getShape());
 		}
 		else
 		{
diff --git a/code/nel/tools/3d/object_viewer/multi_tex_dlg.cpp b/code/nel/tools/3d/object_viewer/multi_tex_dlg.cpp
index 58d67bd0b..ce7162ff8 100644
--- a/code/nel/tools/3d/object_viewer/multi_tex_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/multi_tex_dlg.cpp
@@ -165,19 +165,19 @@ void CMultiTexDlg::readValues(bool alternate)
 	char buf[128];
 	if (!alternate)
 	{
-		GetDlgItem(IDC_U_SPEED_1)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(0).x)));
-		GetDlgItem(IDC_V_SPEED_1)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(0).y)));
-		GetDlgItem(IDC_U_SPEED_2)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(1).x)));
-		GetDlgItem(IDC_V_SPEED_2)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(1).y)));
+		GetDlgItem(IDC_U_SPEED_1)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(0).x)));
+		GetDlgItem(IDC_V_SPEED_1)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(0).y)));
+		GetDlgItem(IDC_U_SPEED_2)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(1).x)));
+		GetDlgItem(IDC_V_SPEED_2)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getScrollSpeed(1).y)));
 	}
 	else
 	{
 		if (_MTP->isAlternateTexEnabled())
 		{
-			GetDlgItem(IDC_U_SPEED_1_ALTERNATE)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(0).x)));
-			GetDlgItem(IDC_V_SPEED_1_ALTERNATE)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(0).y)));
-			GetDlgItem(IDC_U_SPEED_2_ALTERNATE)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(1).x)));
-			GetDlgItem(IDC_V_SPEED_2_ALTERNATE)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(1).y)));
+			GetDlgItem(IDC_U_SPEED_1_ALTERNATE)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(0).x)));
+			GetDlgItem(IDC_V_SPEED_1_ALTERNATE)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(0).y)));
+			GetDlgItem(IDC_U_SPEED_2_ALTERNATE)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(1).x)));
+			GetDlgItem(IDC_V_SPEED_2_ALTERNATE)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getAlternateScrollSpeed(1).y)));
 		}
 		else
 		{
@@ -188,7 +188,7 @@ void CMultiTexDlg::readValues(bool alternate)
 		}
 	}
 
-	GetDlgItem(IDC_BUMP_FACTOR)->SetWindowText(utf8ToTStr(NLMISC::toString("%.3f", _MTP->getBumpFactor())));
+	GetDlgItem(IDC_BUMP_FACTOR)->SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.3f", _MTP->getBumpFactor())));
 }
 
 
diff --git a/code/nel/tools/3d/object_viewer/object_viewer.cpp b/code/nel/tools/3d/object_viewer/object_viewer.cpp
index f1f663e38..be20979b6 100644
--- a/code/nel/tools/3d/object_viewer/object_viewer.cpp
+++ b/code/nel/tools/3d/object_viewer/object_viewer.cpp
@@ -535,7 +535,7 @@ void CObjectViewer::loadConfigFile()
 	}
 	catch (const Exception& e)
 	{
-		::MessageBox (NULL, utf8ToTStr(e.what()), _T("Objectviewer.cfg"), MB_OK|MB_ICONEXCLAMATION);
+		::MessageBox(NULL, nlUtf8ToTStr(e.what()), _T("Objectviewer.cfg"), MB_OK | MB_ICONEXCLAMATION);
 	}
 }
 
@@ -823,7 +823,7 @@ bool CObjectViewer::initUI (HWND parent)
 		catch (const NLMISC::EStream &e)
 		{
 			std::string msg = toString("Unable to load the default scheme bank file : %s", e.what());
-			::MessageBox(NULL, utf8ToTStr(msg), _T("Object Viewer"), MB_ICONEXCLAMATION);
+			::MessageBox(NULL, nlUtf8ToTStr(msg), _T("Object Viewer"), MB_ICONEXCLAMATION);
 		}
 	}
 	iF.close();
@@ -840,7 +840,7 @@ bool CObjectViewer::initUI (HWND parent)
 		catch (const Exception& e)
 		{
 			std::string msg = toString("Error while loading default.ovcgf : %s", e.what());
-			::MessageBox (NULL, utf8ToTStr(msg), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+			::MessageBox(NULL, nlUtf8ToTStr(msg), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 		}
 	}
 
@@ -1312,7 +1312,7 @@ void CObjectViewer::go ()
 				);
 
 			// Display
-			_MainFrame->StatusBar.SetWindowText (utf8ToTStr(msgBar));
+			_MainFrame->StatusBar.SetWindowText(nlUtf8ToTStr(msgBar));
 
 			// Display Vegetable info.
 			if(_VegetableDlg!=NULL)
@@ -1794,7 +1794,7 @@ void CObjectViewer::serial (NLMISC::IStream& f)
 						{
 							// Error message
 							std::string message = toString("File not found %s", readed[i].ShapeFilename.c_str());
-							_MainFrame->MessageBox (utf8ToTStr(message), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+							_MainFrame->MessageBox(nlUtf8ToTStr(message), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 
 							// Stop loading
 							break;
@@ -1829,7 +1829,7 @@ void CObjectViewer::serial (NLMISC::IStream& f)
 				{
 					// Error message
 					std::string message = toString("Error loading shape %s: %s", readed[i].ShapeFilename.c_str(), e.what());
-					_MainFrame->MessageBox (utf8ToTStr(message), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+					_MainFrame->MessageBox(nlUtf8ToTStr(message), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 
 					// Stop loading
 					break;
@@ -1899,7 +1899,7 @@ bool CObjectViewer::loadInstanceGroup(const std::string &igFilename)
 		{
 			// clean
 			delete ig;
-			_MainFrame->MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+			_MainFrame->MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			return false;
 		}
 	}
@@ -1907,7 +1907,7 @@ bool CObjectViewer::loadInstanceGroup(const std::string &igFilename)
 	{
 		// Create a message
 		std::string msg = toString("Can't open the file %s for reading.", igFilename.c_str());
-		_MainFrame->MessageBox (utf8ToTStr(msg), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+		_MainFrame->MessageBox(nlUtf8ToTStr(msg), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 		return false;
 	}
 
@@ -1962,7 +1962,7 @@ bool CObjectViewer::loadMesh (std::vector<std::string> &meshFilename, const std:
 			}
 			catch (const Exception& e)
 			{
-				_MainFrame->MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				_MainFrame->MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 
 				// error
 				skelError=true;
@@ -1972,7 +1972,7 @@ bool CObjectViewer::loadMesh (std::vector<std::string> &meshFilename, const std:
 		{
 			// Create a message
 			std::string msg = NLMISC::toString("Can't open the file %s for reading.", skeleton.c_str());
-			_MainFrame->MessageBox (utf8ToTStr(msg), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+			_MainFrame->MessageBox(nlUtf8ToTStr(msg), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 
 			// error
 			skelError=true;
@@ -2015,7 +2015,7 @@ bool CObjectViewer::loadMesh (std::vector<std::string> &meshFilename, const std:
 			}
 			catch (const Exception& e)
 			{
-				_MainFrame->MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				_MainFrame->MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 				continue;
 			}
 		}
@@ -2023,7 +2023,7 @@ bool CObjectViewer::loadMesh (std::vector<std::string> &meshFilename, const std:
 		{
 			// Create a message
 			std::string msg = NLMISC::toString("Can't open the file %s for reading.", fileName.c_str());
-			_MainFrame->MessageBox (utf8ToTStr(msg), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+			_MainFrame->MessageBox(nlUtf8ToTStr(msg), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			continue;
 		}
 
@@ -2848,7 +2848,7 @@ void CObjectViewer::enableDynamicObjectLightingTest(NLPACS::CGlobalRetriever *gl
 			if (!_ObjectLightTestShape.empty())
 			{			
 				string	str= string("Path not found for Light Test Shape: ") + _ObjectLightTestShape;
-				::MessageBox(NULL, utf8ToTStr(str.c_str()), _T("Dynamic Object Light Test"), MB_OK|MB_ICONEXCLAMATION);
+				::MessageBox(NULL, nlUtf8ToTStr(str.c_str()), _T("Dynamic Object Light Test"), MB_OK | MB_ICONEXCLAMATION);
 			}
 			// disable.
 			_ObjectLightTest= NULL;
@@ -3223,7 +3223,7 @@ bool		CObjectViewer::createVegetableLandscape()
 			// close the progress dialog
 			dlgProgress.DestroyWindow();
 
-			MessageBox(_MainFrame->m_hWnd, utf8ToTStr(e.what()), _T("Failed to Load landscape"), MB_OK | MB_APPLMODAL);
+			MessageBox(_MainFrame->m_hWnd, nlUtf8ToTStr(e.what()), _T("Failed to Load landscape"), MB_OK | MB_APPLMODAL);
 
 			// remove first possibly created collisions objects.
 			if(_VegetableCollisionEntity)
@@ -3557,7 +3557,7 @@ void CObjectViewer::loadAnimation(const std::string &fileName, uint instance)
 	{
 		// Create a message
 		std::string msg = NLMISC::toString("Can't open the file %s for reading.", fileName.c_str());
-		_MainFrame->MessageBox (utf8ToTStr(msg), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+		_MainFrame->MessageBox(nlUtf8ToTStr(msg), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 	}
 }
 
@@ -3587,7 +3587,7 @@ void CObjectViewer::loadSWT (const std::string &fileName, uint instance)
 	{
 		// Create a message
 		std::string msg = NLMISC::toString("Can't open the file %s for reading.", fileName.c_str());
-		_MainFrame->MessageBox (utf8ToTStr(msg), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+		_MainFrame->MessageBox(nlUtf8ToTStr(msg), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 	}
 }
 
@@ -3771,14 +3771,14 @@ void		CObjectViewer::shootScene()
 					else
 					{
 						std::string message = toString("Can't open the file %s for writing.", filenamefinal.c_str());
-						_MainFrame->MessageBox (utf8ToTStr(message), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+						_MainFrame->MessageBox(nlUtf8ToTStr(message), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 						break;
 					}
 				}
 				catch (const Exception &e)
 				{
 					std::string message = toString("Error during writing of the file %s: %s", filenamefinal.c_str(), e.what());
-					_MainFrame->MessageBox (utf8ToTStr(message), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+					_MainFrame->MessageBox(nlUtf8ToTStr(message), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 					break;
 				}
 			}
diff --git a/code/nel/tools/3d/object_viewer/particle_dlg.cpp b/code/nel/tools/3d/object_viewer/particle_dlg.cpp
index f50fe53a2..b7dd9dab3 100644
--- a/code/nel/tools/3d/object_viewer/particle_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/particle_dlg.cpp
@@ -428,7 +428,7 @@ bool CParticleDlg::savePSAs(HWND parent, CParticleWorkspace::CNode &psNode ,cons
 		}
 		else
 		{
-			::MessageBox(parent, utf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_ICONEXCLAMATION);
+			::MessageBox(parent, nlUtf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_ICONEXCLAMATION);
 			return false;
 		}
 	}
@@ -474,7 +474,7 @@ bool CParticleDlg::loadPS(HWND parent, CParticleWorkspace::CNode &psNode, TLoadP
 		{
 			case Silent: return false; // no op
 			case ReportError:	
-				::MessageBox(parent, utf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_OK|MB_ICONEXCLAMATION);
+				::MessageBox(parent, nlUtf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_OK | MB_ICONEXCLAMATION);
 				return true;
 			break;
 			case ReportErrorSkippable:
@@ -549,7 +549,7 @@ void CParticleDlg::OnCreateNewPsWorkspace()
 			}
 			catch(const NLMISC::EStream &e)
 			{
-				MessageBox(utf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_ICONEXCLAMATION);
 			}
 			closeWorkspace();			
 			_PW = newPW;
@@ -567,7 +567,7 @@ void CParticleDlg::OnLoadPSWorkspace()
 	CFileDialog fd( TRUE, _T(".pws"), _T("*.pws"), 0, szFilter);
 	INT_PTR result = fd.DoModal();
 	if (result != IDOK) return;
-	loadWorkspace(tStrToUtf8(fd.GetPathName()));
+	loadWorkspace(NLMISC::tStrToUtf8(fd.GetPathName()));
 }
 
 //**************************************************************************************************************************
@@ -585,7 +585,7 @@ void CParticleDlg::loadWorkspace(const std::string &fullPath)
 	}
 	catch(const NLMISC::EStream &e)
 	{
-		MessageBox(utf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_ICONEXCLAMATION);
+		MessageBox(nlUtf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_ICONEXCLAMATION);
 		setStatusBarText(CString(e.what()));
 		return;
 	}	
@@ -635,7 +635,7 @@ void CParticleDlg::saveWorkspaceStructure()
 	}
 	catch(const NLMISC::EStream &e)
 	{
-		localizedMessageBox(*this, utf8ToTStr(e.what()), IDS_ERROR, MB_ICONEXCLAMATION);
+		localizedMessageBox(*this, nlUtf8ToTStr(e.what()), IDS_ERROR, MB_ICONEXCLAMATION);
 		setStatusBarText(CString(e.what()));
 	}
 }
diff --git a/code/nel/tools/3d/object_viewer/particle_tree_ctrl.cpp b/code/nel/tools/3d/object_viewer/particle_tree_ctrl.cpp
index daad7864a..00793a2c4 100644
--- a/code/nel/tools/3d/object_viewer/particle_tree_ctrl.cpp
+++ b/code/nel/tools/3d/object_viewer/particle_tree_ctrl.cpp
@@ -213,7 +213,7 @@ HTREEITEM CParticleTreeCtrl::buildTreeFromPS(CParticleWorkspace::CNode &node,  H
 	if (node.isLoaded())
 	{	
 		// bind particle system icon
-		HTREEITEM psRoot =  InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT, utf8ToTStr(computeCaption(node)),  PSIconParticleSystem,  PSIconParticleSystem,  0,  0,  NULL,  rootHandle,  prevSibling);
+		HTREEITEM psRoot = InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT, nlUtf8ToTStr(computeCaption(node)), PSIconParticleSystem, PSIconParticleSystem, 0, 0, NULL, rootHandle, prevSibling);
 		// set the param (doesn't seems to work during first creation)
 		SetItemData(psRoot,  (LPARAM) nt);
 		// now,  create each located		
@@ -228,7 +228,7 @@ HTREEITEM CParticleTreeCtrl::buildTreeFromPS(CParticleWorkspace::CNode &node,  H
 	else
 	{
 		// bind a bitmap that say that the PS hasn't been loaded
-		HTREEITEM psRoot =  InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT, utf8ToTStr(computeCaption(node)),  PSIconParticleSystemNotLoaded,  PSIconParticleSystemNotLoaded,  0,  0,  NULL,  rootHandle,  prevSibling);
+		HTREEITEM psRoot = InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT, nlUtf8ToTStr(computeCaption(node)), PSIconParticleSystemNotLoaded, PSIconParticleSystemNotLoaded, 0, 0, NULL, rootHandle, prevSibling);
 		SetItemData(psRoot,  (LPARAM) nt);
 		return psRoot;
 	}
@@ -242,7 +242,7 @@ void CParticleTreeCtrl::buildTreeFromWorkSpace(CParticleWorkspace &ws)
 	CNodeType *nt = new CNodeType(&ws);
 	_NodeTypes.push_back(nt);
 	// bind particle system icon
-	HTREEITEM rootHandle =  InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT, utf8ToTStr(computeCaption(ws)),  PSIconWorkspace,  PSIconWorkspace,  0,  0,  NULL,  NULL,  TVI_LAST);
+	HTREEITEM rootHandle = InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT, nlUtf8ToTStr(computeCaption(ws)), PSIconWorkspace, PSIconWorkspace, 0, 0, NULL, NULL, TVI_LAST);
 	// set the param (doesn't seems to work during first creation)
 	SetItemData(rootHandle,  (LPARAM) nt);
 	// now,  create each particle system
@@ -259,7 +259,7 @@ void CParticleTreeCtrl::createNodeFromLocated(NL3D::CPSLocated *loc,  HTREEITEM
 	CNodeType *nt = new CNodeType(loc);
 	_NodeTypes.push_back(nt);
 	// bind located icon
-	HTREEITEM nodeHandle =  InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM |TVIF_TEXT, utf8ToTStr(loc->getName()) ,  PSIconLocated,  PSIconLocated,  0,  0,  (LPARAM) nt,  rootHandle,  TVI_LAST);
+	HTREEITEM nodeHandle = InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT, nlUtf8ToTStr(loc->getName()), PSIconLocated, PSIconLocated, 0, 0, (LPARAM)nt, rootHandle, TVI_LAST);
 	// now,  insert each object that is bound to the located	
 	for (uint l = 0; l < loc->getNbBoundObjects(); ++l)
 	{
@@ -273,7 +273,7 @@ void CParticleTreeCtrl::createNodeFromLocatedBindable(NL3D::CPSLocatedBindable *
 	// we ordered the image so that they match the type for a located bindable (force,  particles,  collision zones...)
 	CNodeType *nt = new CNodeType(lb);
 	_NodeTypes.push_back(nt);
-	InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT , utf8ToTStr(lb->getName()) ,  lb->getType(),  lb->getType(),  PSIconForce,  PSIconForce,  (LPARAM) nt,  rootHandle,  TVI_LAST);
+	InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT, nlUtf8ToTStr(lb->getName()), lb->getType(), lb->getType(), PSIconForce, PSIconForce, (LPARAM)nt, rootHandle, TVI_LAST);
 }
 
 
@@ -1004,7 +1004,7 @@ BOOL CParticleTreeCtrl::OnCmdMsg(UINT nID,  int nCode,  void* pExtra,  AFX_CMDHA
 				nlassert(ownerNode);				
 
 				// Add search path for the texture
-				NLMISC::CPath::addSearchPath (NLMISC::CFile::getPath(tStrToUtf8(fd.GetPathName())));
+			    NLMISC::CPath::addSearchPath(NLMISC::CFile::getPath(NLMISC::tStrToUtf8(fd.GetPathName())));
 
 				CUniquePtr<NL3D::CShapeBank> sb(new NL3D::CShapeBank);
 				CParticleSystemModel *psm  = NULL;
@@ -1012,9 +1012,9 @@ BOOL CParticleTreeCtrl::OnCmdMsg(UINT nID,  int nCode,  void* pExtra,  AFX_CMDHA
 				{					
 					NL3D::CShapeStream ss;
 					NLMISC::CIFile inputFile;
-					inputFile.open(tStrToUtf8(fd.GetPathName()));
+				    inputFile.open(NLMISC::tStrToUtf8(fd.GetPathName()));
 					ss.serial(inputFile);
-					std::string shapeName = NLMISC::CFile::getFilename(tStrToUtf8(fd.GetPathName()));
+				    std::string shapeName = NLMISC::CFile::getFilename(NLMISC::tStrToUtf8(fd.GetPathName()));
 					sb->add(shapeName, ss.getShapePointer());
 					NL3D::CShapeBank *oldSB = CNELU::Scene->getShapeBank();
 					CNELU::Scene->setShapeBank(sb.get());
@@ -1039,7 +1039,7 @@ BOOL CParticleTreeCtrl::OnCmdMsg(UINT nID,  int nCode,  void* pExtra,  AFX_CMDHA
 				}
 				catch(const NLMISC::EStream &e)
 				{
-					MessageBox(utf8ToTStr(e.what()),  getStrRsc(IDS_ERROR),  MB_OK|MB_ICONEXCLAMATION);
+				    MessageBox(nlUtf8ToTStr(e.what()), getStrRsc(IDS_ERROR), MB_OK | MB_ICONEXCLAMATION);
 					return TRUE;
 				}							
 				ownerNode->setResetAutoCountFlag(false);								
@@ -1096,10 +1096,10 @@ BOOL CParticleTreeCtrl::OnCmdMsg(UINT nID,  int nCode,  void* pExtra,  AFX_CMDHA
 				_ParticleDlg->StartStopDlg->stop();
 				std::string fileName = nt->PS->getFilename();
 				static TCHAR BASED_CODE szFilter[] = _T("ps & shapes files(*.ps;*.shape)|*.ps; *.shape||");
-				CFileDialog fd(FALSE,  _T(".ps"), utf8ToTStr(fileName),  OFN_OVERWRITEPROMPT,  szFilter, this);
+			    CFileDialog fd(FALSE, _T(".ps"), nlUtf8ToTStr(fileName), OFN_OVERWRITEPROMPT, szFilter, this);
 				if (fd.DoModal() == IDOK)
 				{
-					_ParticleDlg->savePSAs(*this, *nt->PS, tStrToUtf8(fd.GetPathName()), false);
+				    _ParticleDlg->savePSAs(*this, *nt->PS, NLMISC::tStrToUtf8(fd.GetPathName()), false);
 				}
 			}
 		}
@@ -1249,7 +1249,7 @@ BOOL CParticleTreeCtrl::OnCmdMsg(UINT nID,  int nCode,  void* pExtra,  AFX_CMDHA
 		}
 		getOwnerNode(nt)->setModified(true);
 		// TODO : an enum for CPSLocatedBindable::getType would be better...
-		InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT, utf8ToTStr(toCreate->getName()),  toCreate->getType(),  toCreate->getType(),  0,  0,  (LPARAM) newNt,  father,  lastSon);
+		InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT, nlUtf8ToTStr(toCreate->getName()), toCreate->getType(), toCreate->getType(), 0, 0, (LPARAM)newNt, father, lastSon);
 		touchPSState(nt);		
 		Invalidate();		
 		_ParticleDlg->StartStopDlg->resetAutoCount(getOwnerNode(nt));
@@ -1280,7 +1280,7 @@ std::pair<CParticleTreeCtrl::CNodeType *,  HTREEITEM> CParticleTreeCtrl::createL
 	CNodeType *newNt = new CNodeType(loc);
 	_NodeTypes.push_back(newNt);
 	// insert item in tree
-	HTREEITEM insertedItem = InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT, utf8ToTStr(name),  PSIconLocated,  PSIconLocated,  0,  0,  (LPARAM) newNt,  headItem,  TVI_LAST);
+	HTREEITEM insertedItem = InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT, nlUtf8ToTStr(name), PSIconLocated, PSIconLocated, 0, 0, (LPARAM)newNt, headItem, TVI_LAST);
 	touchPSState(newNt);	
 	return std::make_pair(newNt,  insertedItem);
 }
@@ -1299,7 +1299,7 @@ void CParticleTreeCtrl::OnEndlabeledit(NMHDR* pNMHDR,  LRESULT* pResult)
 		{
 			case CNodeType::workspace:
 			{
-				nt->WS->setName(tStrToUtf8(info->item.pszText));
+			    nt->WS->setName(NLMISC::tStrToUtf8(info->item.pszText));
 				workspaceModifiedFlagChanged(*nt->WS); // change name (this may be called twice because of the modification callback, but this doesn't matter)
 			}
 			break;
@@ -1311,10 +1311,10 @@ void CParticleTreeCtrl::OnEndlabeledit(NMHDR* pNMHDR,  LRESULT* pResult)
 				}
 				else
 				{				
-					nt->PS->getPSPointer()->setName(tStrToUtf8(info->item.pszText));
+					nt->PS->getPSPointer()->setName(NLMISC::tStrToUtf8(info->item.pszText));
 					nt->PS->setModified(true);
 				}
-				this->SetItemText(info->item.hItem, utf8ToTStr(computeCaption(*nt->PS)));
+			    this->SetItemText(info->item.hItem, nlUtf8ToTStr(computeCaption(*nt->PS)));
 			}
 			break;
 			case CNodeType::located:
@@ -1322,7 +1322,7 @@ void CParticleTreeCtrl::OnEndlabeledit(NMHDR* pNMHDR,  LRESULT* pResult)
 				nlassert(getOwnerNode(nt));
 				getOwnerNode(nt)->setModified(true);
 				this->SetItemText(info->item.hItem,  info->item.pszText);
-				nt->Loc->setName(tStrToUtf8(info->item.pszText));
+			    nt->Loc->setName(NLMISC::tStrToUtf8(info->item.pszText));
 			}
 			break;
 			case CNodeType::locatedBindable:
@@ -1330,7 +1330,7 @@ void CParticleTreeCtrl::OnEndlabeledit(NMHDR* pNMHDR,  LRESULT* pResult)
 				nlassert(getOwnerNode(nt));
 				getOwnerNode(nt)->setModified(true);
 				this->SetItemText(info->item.hItem,  info->item.pszText);
-				nt->Bind->setName(tStrToUtf8(info->item.pszText));
+			    nt->Bind->setName(NLMISC::tStrToUtf8(info->item.pszText));
 			}
 			break;
 		}
@@ -1466,7 +1466,7 @@ void CParticleTreeCtrl::updateCaption(CParticleWorkspace::CNode &node)
 	HTREEITEM item = getTreeItem(&node);
 	if (!item) return;
 	// update name of ps to dipslay a star in front of it (this tells that the ps has been modified)
-	SetItemText(item, utf8ToTStr(computeCaption(node)));
+	SetItemText(item, nlUtf8ToTStr(computeCaption(node)));
 }
 
 //****************************************************************************************************************
@@ -1545,7 +1545,7 @@ void CParticleTreeCtrl::insertNewPS(CParticleWorkspace &pws)
 		while (pos)
 		{
 			CString path = fd.GetNextPathName(pos);						
-			CParticleWorkspace::CNode *node = pws.addNode(tStrToUtf8(path));
+			CParticleWorkspace::CNode *node = pws.addNode(NLMISC::tStrToUtf8(path));
 			if (!node)
 			{
 				if (diplayNodeAlreadyInserted)
@@ -1558,7 +1558,7 @@ void CParticleTreeCtrl::insertNewPS(CParticleWorkspace &pws)
 					}
 					else
 					{
-						MessageBox(CString(utf8ToTStr(NLMISC::CFile::getFilename(tStrToUtf8(path)))) + getStrRsc(IDS_PS_ALREADY_INSERTED), getStrRsc(IDS_ERROR), MB_OK|MB_ICONEXCLAMATION);
+						MessageBox(CString(nlUtf8ToTStr(NLMISC::CFile::getFilename(NLMISC::tStrToUtf8(path)))) + getStrRsc(IDS_PS_ALREADY_INSERTED), getStrRsc(IDS_ERROR), MB_OK | MB_ICONEXCLAMATION);
 					}
 				}								
 				continue;				
@@ -1593,7 +1593,7 @@ void CParticleTreeCtrl::insertNewPS(CParticleWorkspace &pws)
 			}
 		}
 		// update modified state
-		SetItemText(GetRootItem(), utf8ToTStr(computeCaption(pws)));
+		SetItemText(GetRootItem(), nlUtf8ToTStr(computeCaption(pws)));
 	}
 	
 }
@@ -1736,7 +1736,7 @@ void CParticleTreeCtrl::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
 		switch (nt->Type)
 		{
 			case CNodeType::workspace:
-				pEdit->SetWindowText(utf8ToTStr(nt->WS->getName()));
+			pEdit->SetWindowText(nlUtf8ToTStr(nt->WS->getName()));
 			break;
 			case CNodeType::particleSystem:
 			{
@@ -1747,18 +1747,18 @@ void CParticleTreeCtrl::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
 				}
 				else
 				{				
-					pEdit->SetWindowText(utf8ToTStr(nt->PS->getPSPointer()->getName()));
+					pEdit->SetWindowText(nlUtf8ToTStr(nt->PS->getPSPointer()->getName()));
 				}				
 			}
 			break;
 			case CNodeType::located:
 			{				
-				pEdit->SetWindowText(utf8ToTStr(nt->Loc->getName()));
+				pEdit->SetWindowText(nlUtf8ToTStr(nt->Loc->getName()));
 			}
 			break;
 			case CNodeType::locatedBindable:
 			{
-				pEdit->SetWindowText(utf8ToTStr(nt->Bind->getName()));
+			    pEdit->SetWindowText(nlUtf8ToTStr(nt->Bind->getName()));
 			}
 			break;
 		}
@@ -1855,10 +1855,10 @@ void CParticleTreeCtrl::updateAllCaptions()
 		switch(nt->Type)
 		{
 			case CNodeType::particleSystem:
-				SetItemText(curr, utf8ToTStr(computeCaption(*nt->PS)));
+				SetItemText(curr, nlUtf8ToTStr(computeCaption(*nt->PS)));
 			break;
 			case CNodeType::workspace:
-				SetItemText(curr, utf8ToTStr(computeCaption(*nt->WS)));
+			    SetItemText(curr, nlUtf8ToTStr(computeCaption(*nt->WS)));
 			break;
 			case CNodeType::located:			
 			case CNodeType::locatedBindable:			
diff --git a/code/nel/tools/3d/object_viewer/particle_workspace.cpp b/code/nel/tools/3d/object_viewer/particle_workspace.cpp
index 1a289d2b0..d5b3869c1 100644
--- a/code/nel/tools/3d/object_viewer/particle_workspace.cpp
+++ b/code/nel/tools/3d/object_viewer/particle_workspace.cpp
@@ -371,13 +371,13 @@ CParticleWorkspace::CNode *CParticleWorkspace::addNode(const std::string &filena
 	TCHAR resultPath[MAX_PATH];
 	std::string dosPath = NLMISC::CPath::standardizeDosPath(getPath());
 	std::string relativePath;
-	if (!PathRelativePathTo(resultPath, utf8ToTStr(dosPath), FILE_ATTRIBUTE_DIRECTORY, utf8ToTStr(filenameWithFullPath), 0))
+	if (!PathRelativePathTo(resultPath, nlUtf8ToTStr(dosPath), FILE_ATTRIBUTE_DIRECTORY, nlUtf8ToTStr(filenameWithFullPath), 0))
 	{
 		relativePath = filenameWithFullPath; 
 	}
 	else
 	{
-		relativePath = tStrToUtf8(resultPath);
+		relativePath = NLMISC::tStrToUtf8(resultPath);
 	}
 
 	if (relativePath.size() >= 2)
diff --git a/code/nel/tools/3d/object_viewer/pick_sound.cpp b/code/nel/tools/3d/object_viewer/pick_sound.cpp
index 0e6c175d0..0877564d2 100644
--- a/code/nel/tools/3d/object_viewer/pick_sound.cpp
+++ b/code/nel/tools/3d/object_viewer/pick_sound.cpp
@@ -74,7 +74,7 @@ BOOL CPickSound::OnInitDialog()
 	
 	for (TNameVect::iterator it = _Names.begin(); it	!= _Names.end(); ++it)
 	{
-		m_NameList.AddString(utf8ToTStr((*it).toString()));
+		m_NameList.AddString(nlUtf8ToTStr((*it).toString()));
 	}
 
 	_Timer = SetTimer (1, 100, NULL);
@@ -111,7 +111,7 @@ void CPickSound::OnSelchange()
 	nlassert(m_NameList.GetTextLen(m_NameList.GetCurSel()) < 1024);
 	
 	m_NameList.GetText(m_NameList.GetCurSel(), str);
-	_CurrName = NLMISC::CSheetId(tStrToUtf8(str), "sound"); 
+	_CurrName = NLMISC::CSheetId(NLMISC::tStrToUtf8(str), "sound"); 
 	
 }
 
@@ -123,7 +123,7 @@ void CPickSound::OnPlaySound()
 	stopCurrSource();
 	CString sName;
 	m_NameList.GetText(curSel, sName);
-	CSoundSystem::create(tStrToUtf8(sName));
+	CSoundSystem::create(NLMISC::tStrToUtf8(sName));
 }
 
 //========================================================================================
@@ -159,7 +159,7 @@ void CPickSound::OnDblclkList()
 	stopCurrSource();
 	CString sName;
 	m_NameList.GetText(curSel, sName);
-	_CurrSource = CSoundSystem::create(tStrToUtf8(sName));
+	_CurrSource = CSoundSystem::create(NLMISC::tStrToUtf8(sName));
 }
 
 //========================================================================================
diff --git a/code/nel/tools/3d/object_viewer/precomputed_rotations_dlg.cpp b/code/nel/tools/3d/object_viewer/precomputed_rotations_dlg.cpp
index 4f1374eb2..8897955f5 100644
--- a/code/nel/tools/3d/object_viewer/precomputed_rotations_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/precomputed_rotations_dlg.cpp
@@ -126,7 +126,7 @@ void CPrecomputedRotationsDlg::OnUpdateMinRotSpeed()
 	nlassert(_RotatedParticle);
 	UpdateData();
 	float newValue, valueMin, valueMax;
-	if (NLMISC::fromString(tStrToUtf8(m_RotSpeedMin), newValue))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(m_RotSpeedMin), newValue))
 	{
 		uint32 nbModels = _RotatedParticle->checkHintRotateTheSame(valueMin, valueMax);
 		valueMin = newValue;
@@ -146,7 +146,7 @@ void CPrecomputedRotationsDlg::OnUpdateMaxRotSpeed()
 	nlassert(_RotatedParticle);
 	UpdateData();
 	float newValue, valueMin, valueMax;
-	if (NLMISC::fromString(tStrToUtf8(m_RotSpeedMax), newValue))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(m_RotSpeedMax), newValue))
 	{
 		uint32 nbModels = _RotatedParticle->checkHintRotateTheSame(valueMin, valueMax);
 		valueMax = newValue;
@@ -167,7 +167,7 @@ void CPrecomputedRotationsDlg::OnUpdateNbModels()
 	UpdateData();
 	float valueMin, valueMax;
 	sint32 newNbModels;
-	bool valid = (NLMISC::fromString(tStrToUtf8(m_NbModels), newNbModels) && newNbModels > 0);
+	bool valid = (NLMISC::fromString(NLMISC::tStrToUtf8(m_NbModels), newNbModels) && newNbModels > 0);
 	if (dynamic_cast<NL3D::CPSConstraintMesh *>(_RotatedParticle))
 	{
 		valid &= (newNbModels < NL3D::ConstraintMeshMaxNumPrerotatedModels);
diff --git a/code/nel/tools/3d/object_viewer/ps_mover_dlg.cpp b/code/nel/tools/3d/object_viewer/ps_mover_dlg.cpp
index cdd88ea70..e1ac67c30 100644
--- a/code/nel/tools/3d/object_viewer/ps_mover_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/ps_mover_dlg.cpp
@@ -120,7 +120,7 @@ void CPSMoverDlg::OnUpdateXpos()
 	UpdateData();
 	NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex];
 	float x;
-	if (NLMISC::fromString(tStrToUtf8(m_X), x))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(m_X), x))
 	{
 		pos.x = x;
 		updateListener();
@@ -137,7 +137,7 @@ void CPSMoverDlg::OnUpdateYpos()
 	UpdateData();
 	NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex];
 	float y;
-	if (NLMISC::fromString(tStrToUtf8(m_Y), y))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(m_Y), y))
 	{
 		pos.y = y;
 		updateListener();
@@ -154,7 +154,7 @@ void CPSMoverDlg::OnUpdateZpos()
 	UpdateData();
 	NLMISC::CVector &pos = _EditedLocated->getPos()[_EditedLocatedIndex];
 	float z;
-	if (NLMISC::fromString(tStrToUtf8(m_Z), z))
+	if (NLMISC::fromString(NLMISC::tStrToUtf8(m_Z), z))
 	{
 		pos.z = z;
 		updateListener();		
@@ -178,7 +178,7 @@ BOOL CPSMoverDlg::OnInitDialog()
 	{
 		if (dynamic_cast<NL3D::IPSMover *>(_EditedLocated->getBoundObject(k)))
 		{
-			uint insertedLine = m_SubComponentCtrl.AddString(utf8ToTStr(_EditedLocated->getBoundObject(k)->getName()));
+			uint insertedLine = m_SubComponentCtrl.AddString(nlUtf8ToTStr(_EditedLocated->getBoundObject(k)->getName()));
 			m_SubComponentCtrl.SetItemData(insertedLine, (DWORD_PTR) _EditedLocated->getBoundObject(k));
 			++nbCandidates;			
 		}
diff --git a/code/nel/tools/3d/object_viewer/scheme_bank_dlg.cpp b/code/nel/tools/3d/object_viewer/scheme_bank_dlg.cpp
index 2db27bc35..10ebbbfcb 100644
--- a/code/nel/tools/3d/object_viewer/scheme_bank_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/scheme_bank_dlg.cpp
@@ -84,7 +84,7 @@ void CSchemeBankDlg::buildList()
 	SchemeManager.getSchemes(_Type, schemes);
 	for (TSchemeVect::const_iterator it = schemes.begin(); it != schemes.end(); ++it)
 	{
-		int index = m_SchemeList.AddString(utf8ToTStr(it->first));
+		int index = m_SchemeList.AddString(nlUtf8ToTStr(it->first));
 		m_SchemeList.SetItemData(index, (DWORD_PTR) it->second);
 	}
 
@@ -99,18 +99,18 @@ void CSchemeBankDlg::OnSaveBank()
 	if (fd.DoModal() == IDOK)
 	{
 		// Add search path for the texture
-		NLMISC::CPath::addSearchPath (NLMISC::CFile::getPath(tStrToUtf8(fd.GetPathName())));
+		NLMISC::CPath::addSearchPath(NLMISC::CFile::getPath(NLMISC::tStrToUtf8(fd.GetPathName())));
 		
 		try
 		{
 			NLMISC::COFile iF;
-			iF.open(tStrToUtf8(fd.GetFileName()));
+			iF.open(NLMISC::tStrToUtf8(fd.GetFileName()));
 			iF.serial(SchemeManager);			
 		}
 		catch (const std::exception &e)
 		{
 			std::string message = NLMISC::toString("Error saving scheme bank : %s", e.what());
-			MessageBox(utf8ToTStr(message), _T("Object viewer"), MB_ICONEXCLAMATION | MB_OK);
+			MessageBox(nlUtf8ToTStr(message), _T("Object viewer"), MB_ICONEXCLAMATION | MB_OK);
 			return;
 		}		
 	}	
@@ -124,20 +124,20 @@ void CSchemeBankDlg::OnLoadBank()
 	if (fd.DoModal() == IDOK)
 	{
 		// Add search path for the texture
-		NLMISC::CPath::addSearchPath(NLMISC::CFile::getPath(tStrToUtf8(fd.GetPathName())));
+		NLMISC::CPath::addSearchPath(NLMISC::CFile::getPath(NLMISC::tStrToUtf8(fd.GetPathName())));
 
 		CSchemeManager sm;
 		try
 		{
 			NLMISC::CIFile iF;
-			iF.open(NLMISC::CPath::lookup(tStrToUtf8(fd.GetFileName())));
+			iF.open(NLMISC::CPath::lookup(NLMISC::tStrToUtf8(fd.GetFileName())));
 			iF.serial(sm);
 			SchemeManager.swap(sm);
 		}
 		catch (const std::exception &e)
 		{
 			std::string message = NLMISC::toString("Error loading scheme bank : %s", e.what());
-			MessageBox(utf8ToTStr(message), _T("Object viewer"), MB_ICONEXCLAMATION | MB_OK);
+			MessageBox(nlUtf8ToTStr(message), _T("Object viewer"), MB_ICONEXCLAMATION | MB_OK);
 			return;
 		}
 		buildList();
@@ -167,7 +167,7 @@ void CSchemeBankDlg::OnRename()
 		SchemeManager.rename(scheme, cn.getName());
 		int curSel = m_SchemeList.GetCurSel();
 		m_SchemeList.DeleteString(curSel);
-		int insertedPos = m_SchemeList.InsertString(curSel, utf8ToTStr(cn.getName()));
+		int insertedPos = m_SchemeList.InsertString(curSel, nlUtf8ToTStr(cn.getName()));
 		m_SchemeList.SetCurSel(insertedPos);
 		m_SchemeList.Invalidate();
 	}	
diff --git a/code/nel/tools/3d/object_viewer/select_string.cpp b/code/nel/tools/3d/object_viewer/select_string.cpp
index f506d905b..d38285a70 100644
--- a/code/nel/tools/3d/object_viewer/select_string.cpp
+++ b/code/nel/tools/3d/object_viewer/select_string.cpp
@@ -77,14 +77,14 @@ BOOL CSelectString::OnInitDialog()
 	CDialog::OnInitDialog();
 	
 	// Change title
-	SetWindowText (utf8ToTStr(Title));
+	SetWindowText(nlUtf8ToTStr(Title));
 
 	// Empty button ?
 	EmptyCtrl.ShowWindow (Empty?SW_SHOW:SW_HIDE);
 
 	// Add string
 	for (uint s=0; s<Strings.size(); s++)
-		ListCtrl.InsertString (-1, utf8ToTStr(Strings[s]));
+		ListCtrl.InsertString(-1, nlUtf8ToTStr(Strings[s]));
 	
 	return TRUE;  // return TRUE unless you set the focus to a control
 	              // EXCEPTION: OCX Property Pages should return FALSE
diff --git a/code/nel/tools/3d/object_viewer/skeleton_scale_dlg.cpp b/code/nel/tools/3d/object_viewer/skeleton_scale_dlg.cpp
index f54c723df..d444bb31e 100644
--- a/code/nel/tools/3d/object_viewer/skeleton_scale_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/skeleton_scale_dlg.cpp
@@ -209,7 +209,7 @@ void		CSkeletonScaleDlg::setSkeletonToEdit(NL3D::CSkeletonModel *skel, const std
 				name = tabStr + name;
 
 			// append to the list
-			_BoneList.AddString(utf8ToTStr(name));
+			_BoneList.AddString(nlUtf8ToTStr(name));
 		}
 	}
 
@@ -404,7 +404,7 @@ void		CSkeletonScaleDlg::applyScaleSlider(sint scrollValue)
 
 	// update marker text
 	std::string	str = NLMISC::toString("%d%%", (sint)(factor*100));
-	_StaticScaleMarkers[_SliderEdited]->SetWindowText(utf8ToTStr(str));
+	_StaticScaleMarkers[_SliderEdited]->SetWindowText(nlUtf8ToTStr(str));
 }
 
 // ***************************************************************************
@@ -717,7 +717,7 @@ void CSkeletonScaleDlg::updateScalesFromText(UINT ctrlId)
 		return;
 
 	// get the scale info
-	std::string	str = tStrToUtf8(*_ScaleEdits[sid]);
+	std::string str = NLMISC::tStrToUtf8(*_ScaleEdits[sid]);
 	if(str.empty())
 		return;
 	float	f;
@@ -846,13 +846,13 @@ void CSkeletonScaleDlg::OnSsdButtonSaveas()
 		return;
 
 	// choose the file
-	CFileDialog fd(FALSE, _T("skel"), utf8ToTStr(_SkeletonFileName), OFN_OVERWRITEPROMPT, _T("SkelFiles (*.skel)|*.skel|All Files (*.*)|*.*||"), this) ;
+	CFileDialog fd(FALSE, _T("skel"), nlUtf8ToTStr(_SkeletonFileName), OFN_OVERWRITEPROMPT, _T("SkelFiles (*.skel)|*.skel|All Files (*.*)|*.*||"), this);
 	fd.m_ofn.lpstrTitle = _T("Save As Skeleton");
 	if (fd.DoModal() == IDOK)
 	{
 		NLMISC::COFile	f;
 		
-		if( f.open(tStrToUtf8(fd.GetPathName())) )
+		if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
 		{
 			if(saveCurrentInStream(f))
 			{
@@ -862,7 +862,7 @@ void CSkeletonScaleDlg::OnSsdButtonSaveas()
 			}
 
 			// bkup the valid fileName (new file edited)
-			_SkeletonFileName= tStrToUtf8(fd.GetPathName());
+			_SkeletonFileName = NLMISC::tStrToUtf8(fd.GetPathName());
 			_StaticFileName= _SkeletonFileName.c_str();
 			UpdateData(FALSE);
 		}
@@ -1228,13 +1228,13 @@ void CSkeletonScaleDlg::OnSsdButtonSaveScale()
 	std::string	defaultFileName = _SkeletonFileName;
 	NLMISC::strFindReplace(defaultFileName, ".skel", ".scale");
 
-	CFileDialog fd(FALSE, _T("scale"), utf8ToTStr(defaultFileName), OFN_OVERWRITEPROMPT, _T("SkelScaleFiles (*.scale)|*.scale|All Files (*.*)|*.*||"), this) ;
+	CFileDialog fd(FALSE, _T("scale"), nlUtf8ToTStr(defaultFileName), OFN_OVERWRITEPROMPT, _T("SkelScaleFiles (*.scale)|*.scale|All Files (*.*)|*.*||"), this);
 	fd.m_ofn.lpstrTitle = _T("Save As Skeleton Scale File");
 
 	if (fd.DoModal() == IDOK)
 	{
 		NLMISC::COFile	f;
-		if (f.open(tStrToUtf8(fd.GetPathName())))
+		if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
 		{
 			saveSkelScaleInStream(f);
 		}
@@ -1256,13 +1256,13 @@ void CSkeletonScaleDlg::OnSsdButtonLoadScale()
 	std::string	defaultFileName= _SkeletonFileName;
 	NLMISC::strFindReplace(defaultFileName, ".skel", ".scale");
 
-	CFileDialog fd(TRUE, _T("scale"), utf8ToTStr(defaultFileName), 0, _T("SkelScaleFiles (*.scale)|*.scale|All Files (*.*)|*.*||"), this) ;
+	CFileDialog fd(TRUE, _T("scale"), nlUtf8ToTStr(defaultFileName), 0, _T("SkelScaleFiles (*.scale)|*.scale|All Files (*.*)|*.*||"), this);
 	fd.m_ofn.lpstrTitle= _T("Load a Skeleton Scale File");
 
 	if (fd.DoModal() == IDOK)
 	{
 		NLMISC::CIFile	f;
-		if (f.open(tStrToUtf8(fd.GetPathName())))
+		if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
 		{
 			loadSkelScaleFromStream(f);
 		}
diff --git a/code/nel/tools/3d/object_viewer/slot_dlg.cpp b/code/nel/tools/3d/object_viewer/slot_dlg.cpp
index 507c9b4e8..374ac99de 100644
--- a/code/nel/tools/3d/object_viewer/slot_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/slot_dlg.cpp
@@ -472,7 +472,7 @@ void CSlotDlg::setWindowName ()
 		}
 	}
 
-	GetDlgItem (IDC_SLOT_NAME)->SetWindowText (utf8ToTStr(tmp));
+	GetDlgItem(IDC_SLOT_NAME)->SetWindowText(nlUtf8ToTStr(tmp));
 }
 
 // ***************************************************************************
diff --git a/code/nel/tools/3d/object_viewer/snapshot_tool_dlg.cpp b/code/nel/tools/3d/object_viewer/snapshot_tool_dlg.cpp
index a85b8ae9f..ca5b7f549 100644
--- a/code/nel/tools/3d/object_viewer/snapshot_tool_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/snapshot_tool_dlg.cpp
@@ -183,7 +183,7 @@ void CSnapshotToolDlg::fromRegistry()
 
 	for (uint k = 0; k < filterList.size(); ++k)
 	{
-		m_Filters.AddString(utf8ToTStr(filterList[k]));
+		m_Filters.AddString(nlUtf8ToTStr(filterList[k]));
 	}	
 	
 	integralTypeFromRegistry(hKey, _T("RecurseSubFolder"), (int &) m_RecurseSubFolder, FALSE);
@@ -597,7 +597,7 @@ void CSnapshotToolDlg::OnTimer(UINT_PTR nIDEvent)
 		try
 		{
 			CShapeStream ss;
-			m_Log.AddString(utf8ToTStr(_FilteredFiles[0]));
+			m_Log.AddString(nlUtf8ToTStr(_FilteredFiles[0]));
 			CIFile stream(_FilteredFiles[0]);
 			ss.serial(stream);
 			nlassert(ss.getShapePointer());
diff --git a/code/nel/tools/3d/object_viewer/sound_anim_dlg.cpp b/code/nel/tools/3d/object_viewer/sound_anim_dlg.cpp
index 893a6a011..80b0d8507 100644
--- a/code/nel/tools/3d/object_viewer/sound_anim_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/sound_anim_dlg.cpp
@@ -78,7 +78,7 @@ void CSoundAnimDlg::handle()
 {
 	float sec = _AnimationDlg->getTime();
 	std::string text = toString("time: %.3f", sec);
-	GetDlgItem(IDC_SOUNDANIMINFO)->SetWindowText(utf8ToTStr(text));
+	GetDlgItem(IDC_SOUNDANIMINFO)->SetWindowText(nlUtf8ToTStr(text));
 
 	_AnimView.updateCursor(); 
 }
@@ -136,7 +136,7 @@ void CSoundAnimDlg::updateSounds()
 
 		for (iter = sounds.begin(); iter != sounds.end(); iter++)
 		{
-			list->AddString(utf8ToTStr((*iter).toString()));
+			list->AddString(nlUtf8ToTStr((*iter).toString()));
 		}
 
 		list->UpdateData();
diff --git a/code/nel/tools/3d/object_viewer/sound_anim_view.cpp b/code/nel/tools/3d/object_viewer/sound_anim_view.cpp
index 72591a4b4..acc7828c0 100644
--- a/code/nel/tools/3d/object_viewer/sound_anim_view.cpp
+++ b/code/nel/tools/3d/object_viewer/sound_anim_view.cpp
@@ -217,7 +217,7 @@ void CSoundAnimView::save()
 
 				// Create a dialog
 				TCHAR BASED_CODE szFilter[] = _T("NeL Sound Animations (*.sound_anim)|*.sound_anim|All Files (*.*)|*.*||");
-				CFileDialog fileDlg( FALSE, _T(".sound_anim"), utf8ToTStr(filename), OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter);
+				CFileDialog fileDlg(FALSE, _T(".sound_anim"), nlUtf8ToTStr(filename), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
 
 				if (fileDlg.DoModal() == IDOK)
 				{
@@ -236,7 +236,7 @@ void CSoundAnimView::save()
 			}
 			catch (const Exception& e)
 			{
-				MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			}
 		}
 	}
diff --git a/code/nel/tools/3d/object_viewer/start_stop_particle_system.cpp b/code/nel/tools/3d/object_viewer/start_stop_particle_system.cpp
index 923c35ed1..3fbf5b29a 100644
--- a/code/nel/tools/3d/object_viewer/start_stop_particle_system.cpp
+++ b/code/nel/tools/3d/object_viewer/start_stop_particle_system.cpp
@@ -231,13 +231,13 @@ void CStartStopParticleSystem::updateUIFromState()
 	{	
 		if (!_ActiveNode->getParentSkelName().empty())
 		{
-			GetDlgItem(IDC_STICK_BONE)->SetWindowText(utf8ToTStr(_ActiveNode->getParentBoneName() + "." + _ActiveNode->getParentBoneName()));
+			GetDlgItem(IDC_STICK_BONE)->SetWindowText(nlUtf8ToTStr(_ActiveNode->getParentBoneName() + "." + _ActiveNode->getParentBoneName()));
 		}
 		else
 		{
 			GetDlgItem(IDC_STICK_BONE)->SetWindowText(_T(""));
 		}		
-		GetDlgItem(IDC_ACTIVE_PS)->SetWindowText(utf8ToTStr(_ActiveNode->getFilename()));
+		GetDlgItem(IDC_ACTIVE_PS)->SetWindowText(nlUtf8ToTStr(_ActiveNode->getFilename()));
 		GetDlgItem(IDC_ENABLE_AUTO_COUNT)->EnableWindow(TRUE);
 		((CButton *) GetDlgItem(IDC_ENABLE_AUTO_COUNT))->SetCheck(getCurrPS()->getAutoCountFlag() ? 1 : 0);
 		GetDlgItem(IDC_RESET_COUNT)->EnableWindow((_ActiveNode->getPSPointer()->getAutoCountFlag() && !_ActiveNode->getResetAutoCountFlag()) ? TRUE : FALSE);
@@ -844,7 +844,7 @@ void CStartStopParticleSystem::OnLinkToSkeleton()
 	uint boneIndex;
 	std::string parentSkelName;
 	std::string parentBoneName;
-	if (ov->chooseBone(tStrToUtf8(chooseBoneForPS), skel, boneIndex, &parentSkelName, &parentBoneName))
+	if (ov->chooseBone(NLMISC::tStrToUtf8(chooseBoneForPS), skel, boneIndex, &parentSkelName, &parentBoneName))
 	{
 		_ParticleDlg->stickPSToSkeleton(_ActiveNode, skel, boneIndex, parentSkelName, parentBoneName);
 	}
@@ -1017,11 +1017,11 @@ void CStartStopParticleSystem::OnBrowseAnim()
 		}
 	}
 	std::vector<std::string> animList(animSet.begin(), animSet.end());
-	CSelectString st(animList, tStrToUtf8(getStrRsc(IDS_SELECT_ANIMATION)), this, false);
+	CSelectString st(animList, NLMISC::tStrToUtf8(getStrRsc(IDS_SELECT_ANIMATION)), this, false);
 	if (st.DoModal() == IDOK && st.Selection != -1)
 	{
 		m_TriggerAnim = animList[st.Selection].c_str();
-		_ActiveNode->setTriggerAnim(tStrToUtf8(m_TriggerAnim));
+		_ActiveNode->setTriggerAnim(NLMISC::tStrToUtf8(m_TriggerAnim));
 		GetDlgItem(IDC_CLEAR_ANIM)->EnableWindow(!_ActiveNode->getTriggerAnim().empty());
 	}	
 	_ParticleDlg->ParticleTreeCtrl->updateCaption(*_ActiveNode);
diff --git a/code/nel/tools/3d/object_viewer/texture_chooser.cpp b/code/nel/tools/3d/object_viewer/texture_chooser.cpp
index 70cc151b0..e87a33315 100644
--- a/code/nel/tools/3d/object_viewer/texture_chooser.cpp
+++ b/code/nel/tools/3d/object_viewer/texture_chooser.cpp
@@ -179,22 +179,22 @@ void CTextureChooser::OnBrowseTexture()
 	{
 		texName = (static_cast<NL3D::CTextureFile *>(_Wrapper->get()))->getFileName();
 	}
-	CFileDialog fd(TRUE, _T(".tga"), utf8ToTStr(texName), 0, NULL, this);
+	CFileDialog fd(TRUE, _T(".tga"), nlUtf8ToTStr(texName), 0, NULL, this);
 	if (fd.DoModal() == IDOK)
 	{
 		// Add search path for the texture
-		NLMISC::CPath::addSearchPath (NLMISC::CFile::getPath(tStrToUtf8(fd.GetPathName())));
+		NLMISC::CPath::addSearchPath(NLMISC::CFile::getPath(NLMISC::tStrToUtf8(fd.GetPathName())));
 
 		try
 		{
-			NL3D::CTextureFile *tf = new NL3D::CTextureFile(tStrToUtf8(fd.GetFileName()));
+			NL3D::CTextureFile *tf = new NL3D::CTextureFile(NLMISC::tStrToUtf8(fd.GetFileName()));
 			_Wrapper->setAndUpdateModifiedFlag(tf);
 			_Texture = tf;
 			textureToBitmap();
 		}
 		catch (const NLMISC::Exception &e)
 		{
-			MessageBox(utf8ToTStr(e.what()), _T("error loading texture"));
+			MessageBox(nlUtf8ToTStr(e.what()), _T("error loading texture"));
 		}		
 	
 	}
diff --git a/code/nel/tools/3d/object_viewer/vegetable_copy_dlg.cpp b/code/nel/tools/3d/object_viewer/vegetable_copy_dlg.cpp
index 05e0ab1fd..d0015d26d 100644
--- a/code/nel/tools/3d/object_viewer/vegetable_copy_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/vegetable_copy_dlg.cpp
@@ -249,7 +249,7 @@ BOOL CVegetableCopyDlg::OnInitDialog()
 	uint	num= _VegetableDlg->getNumVegetables();
 	for(uint i=0; i<num; i++)
 	{
-		VegetableList.AddString(utf8ToTStr(_VegetableDlg->getVegetableName(i)));
+		VegetableList.AddString(nlUtf8ToTStr(_VegetableDlg->getVegetableName(i)));
 	}
 	
 
diff --git a/code/nel/tools/3d/object_viewer/vegetable_density_page.cpp b/code/nel/tools/3d/object_viewer/vegetable_density_page.cpp
index d8f9c2d75..f86e681a7 100644
--- a/code/nel/tools/3d/object_viewer/vegetable_density_page.cpp
+++ b/code/nel/tools/3d/object_viewer/vegetable_density_page.cpp
@@ -100,7 +100,7 @@ void CVegetableDensityPage::setVegetableToEdit(NL3D::CVegetable *vegetable)
 	{
 		// Init ShapeName
 		// ----------
-		StaticVegetableShape.SetWindowText(utf8ToTStr(_Vegetable->ShapeName));
+		StaticVegetableShape.SetWindowText(nlUtf8ToTStr(_Vegetable->ShapeName));
 
 		// init Creation Distance.
 		// ----------
@@ -228,7 +228,7 @@ void		CVegetableDensityPage::updateAngleMinFromEditText()
 	TCHAR	stmp[256];
 	AngleMinEdit.GetWindowText(stmp, 256);
 	float	angleMin;
-	NLMISC::fromString(tStrToUtf8(stmp), angleMin);
+	NLMISC::fromString(NLMISC::tStrToUtf8(stmp), angleMin);
 	NLMISC::clamp(angleMin, -90, 90);
 	// make a sinus, because 90 => 1, and -90 =>-1
 	float	cosAngleMin= (float)sin(angleMin*NLMISC::Pi/180.f);
@@ -252,7 +252,7 @@ void		CVegetableDensityPage::updateAngleMaxFromEditText()
 	TCHAR	stmp[256];
 	AngleMaxEdit.GetWindowText(stmp, 256);
 	float	angleMax;
-	NLMISC::fromString(tStrToUtf8(stmp), angleMax);
+	NLMISC::fromString(NLMISC::tStrToUtf8(stmp), angleMax);
 	NLMISC::clamp(angleMax, -90, 90);
 	// make a sinus, because 90 => 1, and -90 =>-1
 	float	cosAngleMax= (float)sin(angleMax*NLMISC::Pi/180.f);
@@ -523,10 +523,10 @@ void CVegetableDensityPage::OnButtonVegetableBrowse()
 	if (fd.DoModal() == IDOK)
 	{
 		// Add to the path
-		std::string fileName = tStrToUtf8(fd.GetFileName());
+		std::string fileName = NLMISC::tStrToUtf8(fd.GetFileName());
 
 		// Add search path for the .veget
-		std::string path = NLMISC::CFile::getPath(tStrToUtf8(fd.GetPathName()));
+		std::string path = NLMISC::CFile::getPath(NLMISC::tStrToUtf8(fd.GetPathName()));
 		NLMISC::CPath::addSearchPath (path);
 
 		try
@@ -546,7 +546,7 @@ void CVegetableDensityPage::OnButtonVegetableBrowse()
 		}
 		catch (const NLMISC::EPathNotFound &ep)
 		{
-			MessageBox(utf8ToTStr(ep.what()), _T("Can't open file"));
+			MessageBox(nlUtf8ToTStr(ep.what()), _T("Can't open file"));
 		}
 	}
 }
diff --git a/code/nel/tools/3d/object_viewer/vegetable_dlg.cpp b/code/nel/tools/3d/object_viewer/vegetable_dlg.cpp
index 09a2079e5..d9799408a 100644
--- a/code/nel/tools/3d/object_viewer/vegetable_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/vegetable_dlg.cpp
@@ -196,7 +196,7 @@ void				CVegetableDlg::updateCurSelVegetableName()
 		_Vegetables[id].updateVegetableName();
 		// replace name in the listBox: must delete, and re-insert
 		VegetableList.DeleteString(id);
-		VegetableList.InsertString(id, utf8ToTStr(_Vegetables[id].VegetableName));
+		VegetableList.InsertString(id, nlUtf8ToTStr(_Vegetables[id].VegetableName));
 		VegetableList.SetCurSel(id);
 	}
 }
@@ -349,14 +349,14 @@ bool		CVegetableDlg::loadVegetableSet(NL3D::CTileVegetableDesc &vegetSet, const
 		
 		ok= true;
 
-		if( f.open(tStrToUtf8(fd.GetPathName())))
+		if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
 		{
 			try
 			{
 				// read the vegetable
 				f.serial(vegetSet);
 				// bkup fileName.
-				_LastVegetSetName = tStrToUtf8(fd.GetFileName());
+				_LastVegetSetName = NLMISC::tStrToUtf8(fd.GetFileName());
 			}
 			catch(const NLMISC::EStream &)
 			{
@@ -439,7 +439,7 @@ void		CVegetableDlg::appendVegetableSet(NL3D::CTileVegetableDesc &vegetSet)
 			_Vegetables[id].initVegetable(veget);
 
 			// update view
-			VegetableList.AddString(utf8ToTStr(_Vegetables[id].VegetableName));
+			VegetableList.AddString(nlUtf8ToTStr(_Vegetables[id].VegetableName));
 		}
 	}
 }
@@ -529,7 +529,7 @@ void CVegetableDlg::OnButtonVegetableAdd()
 	_Vegetables[id].initDefaultVegetable();
 
 	// update view
-	VegetableList.AddString(utf8ToTStr(_Vegetables[id].VegetableName));
+	VegetableList.AddString(nlUtf8ToTStr(_Vegetables[id].VegetableName));
 
 	// update 3D view
 	refreshVegetableDisplay();
@@ -559,7 +559,7 @@ void CVegetableDlg::OnButtonVegetableInsert()
 		_Vegetables[id].initDefaultVegetable();
 
 		// update view
-		VegetableList.InsertString(id, utf8ToTStr(_Vegetables[id].VegetableName));
+		VegetableList.InsertString(id, nlUtf8ToTStr(_Vegetables[id].VegetableName));
 
 		// update 3D view
 		refreshVegetableDisplay();
@@ -611,7 +611,7 @@ void CVegetableDlg::OnButtonVegetableLoadDesc()
 	{
 		NLMISC::CIFile	f;
 		
-		if( f.open(tStrToUtf8(fd.GetPathName())) )
+		if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
 		{
 			NL3D::CVegetable	veget;
 			try
@@ -624,7 +624,7 @@ void CVegetableDlg::OnButtonVegetableLoadDesc()
 				_Vegetables[id].initVegetable(veget);
 
 				// update view
-				VegetableList.AddString(utf8ToTStr(_Vegetables[id].VegetableName));
+				VegetableList.AddString(nlUtf8ToTStr(_Vegetables[id].VegetableName));
 
 				// update 3D view
 				refreshVegetableDisplay();
@@ -651,13 +651,13 @@ void CVegetableDlg::OnButtonVegetableSaveDesc()
 
 		std::string		fileName= _Vegetables[id].VegetableName + ".vegetdesc";
 
-		CFileDialog fd(FALSE, _T("vegetdesc"), utf8ToTStr(fileName), OFN_OVERWRITEPROMPT, _T("VegetDescFiles (*.vegetdesc)|*.vegetdesc|All Files (*.*)|*.*||"), this) ;
+		CFileDialog fd(FALSE, _T("vegetdesc"), nlUtf8ToTStr(fileName), OFN_OVERWRITEPROMPT, _T("VegetDescFiles (*.vegetdesc)|*.vegetdesc|All Files (*.*)|*.*||"), this);
 		fd.m_ofn.lpstrTitle = _T("Save Vegetable Descriptor");
 		if (fd.DoModal() == IDOK)
 		{
 			NLMISC::COFile	f;
 			
-			if( f.open(tStrToUtf8(fd.GetPathName())) )
+			if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
 			{
 				try
 				{
@@ -722,13 +722,13 @@ void CVegetableDlg::OnButtonVegetableSaveSet()
 	buildVegetableSet(vegetSet);
 
 	// Then try to save it.
-	CFileDialog fd(FALSE, _T("vegetset"), utf8ToTStr(_LastVegetSetName), OFN_OVERWRITEPROMPT, _T("VegetSetFiles (*.vegetset)|*.vegetset|All Files (*.*)|*.*||"), this) ;
+	CFileDialog fd(FALSE, _T("vegetset"), nlUtf8ToTStr(_LastVegetSetName), OFN_OVERWRITEPROMPT, _T("VegetSetFiles (*.vegetset)|*.vegetset|All Files (*.*)|*.*||"), this);
 	fd.m_ofn.lpstrTitle = _T("Save Vegetable Set");
 	if (fd.DoModal() == IDOK)
 	{
 		NLMISC::COFile	f;
 		
-		if( f.open(tStrToUtf8(fd.GetPathName())) )
+		if (f.open(NLMISC::tStrToUtf8(fd.GetPathName())))
 		{
 			try
 			{
diff --git a/code/nel/tools/3d/object_viewer/vegetable_edit_tools.cpp b/code/nel/tools/3d/object_viewer/vegetable_edit_tools.cpp
index b0508cca9..072d319d7 100644
--- a/code/nel/tools/3d/object_viewer/vegetable_edit_tools.cpp
+++ b/code/nel/tools/3d/object_viewer/vegetable_edit_tools.cpp
@@ -33,7 +33,7 @@ void	CDirectEditableRangeFloat::init(uint32 x, uint32 y, CWnd *pParent)
 
 	CRect	rect;
 	rect.SetRect(x, y+10, x+dx, y+25);
-	_StaticText.Create(utf8ToTStr(_Title), WS_CHILD | WS_VISIBLE, rect, pParent);
+	_StaticText.Create(nlUtf8ToTStr(_Title), WS_CHILD | WS_VISIBLE, rect, pParent);
 	_StaticText.SetFont(pParent->GetFont());
 }
 
diff --git a/code/nel/tools/3d/object_viewer/vegetable_noise_value_dlg.cpp b/code/nel/tools/3d/object_viewer/vegetable_noise_value_dlg.cpp
index 12bfe4050..5b3360898 100644
--- a/code/nel/tools/3d/object_viewer/vegetable_noise_value_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/vegetable_noise_value_dlg.cpp
@@ -154,7 +154,7 @@ BOOL CVegetableNoiseValueDlg::OnInitDialog()
 
 
 	// Set the name.
-	NoiseValueName.SetWindowText(utf8ToTStr(_TitleName));
+	NoiseValueName.SetWindowText(nlUtf8ToTStr(_TitleName));
 
 
 	// if previously setuped, setup now the noiseValue.
@@ -264,5 +264,5 @@ void CVegetableNoiseValueDlg::applyScaleSlider(sint scrollValue)
 	_RandValue->updateValueFromReader();
 
 	// update marker text
-	StaticScaleMarker.SetWindowText(utf8ToTStr(NLMISC::toString("%d%%", (sint)(factor * 100))));
+	StaticScaleMarker.SetWindowText(nlUtf8ToTStr(NLMISC::toString("%d%%", (sint)(factor * 100))));
 }
diff --git a/code/nel/tools/3d/object_viewer/vegetable_select_dlg.cpp b/code/nel/tools/3d/object_viewer/vegetable_select_dlg.cpp
index d7be7bcb3..b6e6df97a 100644
--- a/code/nel/tools/3d/object_viewer/vegetable_select_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/vegetable_select_dlg.cpp
@@ -63,7 +63,7 @@ BOOL CVegetableSelectDlg::OnInitDialog()
 	uint	num= _VegetableDlg->getNumVegetables();
 	for(uint i=0; i<num; i++)
 	{
-		VegetableList.AddString(utf8ToTStr(_VegetableDlg->getVegetableName(i)));
+		VegetableList.AddString(nlUtf8ToTStr(_VegetableDlg->getVegetableName(i)));
 	}
 	
 	return TRUE;  // return TRUE unless you set the focus to a control
diff --git a/code/nel/tools/3d/object_viewer/vegetable_wind_dlg.cpp b/code/nel/tools/3d/object_viewer/vegetable_wind_dlg.cpp
index 0b2084863..79533b623 100644
--- a/code/nel/tools/3d/object_viewer/vegetable_wind_dlg.cpp
+++ b/code/nel/tools/3d/object_viewer/vegetable_wind_dlg.cpp
@@ -73,19 +73,19 @@ void	CVegetableWindDlg::updateView()
 
 	// update Power.
 	a= _ObjViewer->getVegetableWindPower();
-	StaticPower.SetWindowText(utf8ToTStr(NLMISC::toString("%.2f", a)));
+	StaticPower.SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", a)));
 	NLMISC::clamp(a, 0, NL_VEGETABLE_EDIT_WIND_MAX_POWER);
 	SliderPower.SetPos((sint)(a*NL_VEGETABLE_EDIT_WIND_SLIDER_RANGE / NL_VEGETABLE_EDIT_WIND_MAX_POWER));
 
 	// update BendStart.
 	a= _ObjViewer->getVegetableWindBendStart();
-	StaticBendStart.SetWindowText(utf8ToTStr(NLMISC::toString("%.2f", a)));
+	StaticBendStart.SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", a)));
 	NLMISC::clamp(a, 0, NL_VEGETABLE_EDIT_WIND_MAX_BENDSTART);
 	SliderBendStart.SetPos((sint)(a*NL_VEGETABLE_EDIT_WIND_SLIDER_RANGE / NL_VEGETABLE_EDIT_WIND_MAX_BENDSTART));
 
 	// update Frequency.
 	a= _ObjViewer->getVegetableWindFrequency();
-	StaticFrequency.SetWindowText(utf8ToTStr(NLMISC::toString("%.2f", a)));
+	StaticFrequency.SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", a)));
 	NLMISC::clamp(a, 0, NL_VEGETABLE_EDIT_WIND_MAX_FREQUENCY);
 	SliderFrequency.SetPos((sint)(a*NL_VEGETABLE_EDIT_WIND_SLIDER_RANGE / NL_VEGETABLE_EDIT_WIND_MAX_FREQUENCY));
 
@@ -129,20 +129,20 @@ void CVegetableWindDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBa
 		{
 			a= (float)nPos * NL_VEGETABLE_EDIT_WIND_MAX_POWER / NL_VEGETABLE_EDIT_WIND_SLIDER_RANGE;
 			_ObjViewer->setVegetableWindPower(a);
-			StaticPower.SetWindowText(utf8ToTStr(NLMISC::toString("%.2f", a)));
+			StaticPower.SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", a)));
 		}
 		else if(sliderCtrl == &SliderBendStart)
 		{
 			a= (float)nPos * NL_VEGETABLE_EDIT_WIND_MAX_BENDSTART / NL_VEGETABLE_EDIT_WIND_SLIDER_RANGE;
 			_ObjViewer->setVegetableWindBendStart(a);
-			StaticBendStart.SetWindowText(utf8ToTStr(NLMISC::toString("%.2f", a)));
+			StaticBendStart.SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", a)));
 		}
 		else if(sliderCtrl == &SliderFrequency)
 		{
 		
 			a= (float)nPos * NL_VEGETABLE_EDIT_WIND_MAX_FREQUENCY / NL_VEGETABLE_EDIT_WIND_SLIDER_RANGE;
 			_ObjViewer->setVegetableWindFrequency(a);
-			StaticFrequency.SetWindowText(utf8ToTStr(NLMISC::toString("%.2f", a)));
+			StaticFrequency.SetWindowText(nlUtf8ToTStr(NLMISC::toString("%.2f", a)));
 		}
 	}
 	else
diff --git a/code/nel/tools/3d/object_viewer/water_pool_editor.cpp b/code/nel/tools/3d/object_viewer/water_pool_editor.cpp
index bf6f461bf..5f5c0cc24 100644
--- a/code/nel/tools/3d/object_viewer/water_pool_editor.cpp
+++ b/code/nel/tools/3d/object_viewer/water_pool_editor.cpp
@@ -166,7 +166,7 @@ BOOL CWaterPoolEditor::OnInitDialog()
 int CWaterPoolEditor::addPool(uint32 ID)
 {
 	std::string poolId = NLMISC::toString("%d (%s)", ID, _Wpm->getPoolByID(ID).getName().c_str());
-	int index = m_PoolList.AddString(utf8ToTStr(poolId));
+	int index = m_PoolList.AddString(nlUtf8ToTStr(poolId));
 	nlassert(index != LB_ERR);
 	m_PoolList.SetItemData(index, ID);
 	return index;
@@ -357,7 +357,7 @@ void CWaterPoolEditor::OnLoadPool()
 		{
 			NLMISC::CIXml iXml;
 			NLMISC::CIFile iF;
-			if (iF.open(tStrToUtf8(fileDlg.GetPathName())))
+			if (iF.open(NLMISC::tStrToUtf8(fileDlg.GetPathName())))
 			{
 				if (iXml.init (iF))
 				{
@@ -369,17 +369,17 @@ void CWaterPoolEditor::OnLoadPool()
 				else
 				{
 					iF.close();
-					MessageBox (utf8ToTStr(NLMISC::toString("Unable to init xml stream from file: %s", tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+					MessageBox(nlUtf8ToTStr(NLMISC::toString("Unable to init xml stream from file: %s", NLMISC::tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 				}
 			}
 			else
 			{
-				MessageBox (utf8ToTStr(NLMISC::toString("Unable to open file: %s", tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(NLMISC::toString("Unable to open file: %s", NLMISC::tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			}
 		}
 		catch (const NLMISC::Exception& e)
 		{
-			MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 		}
 	}	
 }
@@ -395,7 +395,7 @@ void CWaterPoolEditor::OnSavePool()
 		{
 			NLMISC::COXml oXml;
 			NLMISC::COFile oF;
-			if (oF.open(tStrToUtf8(fileDlg.GetPathName())))
+			if (oF.open(NLMISC::tStrToUtf8(fileDlg.GetPathName())))
 			{
 				if (oXml.init (&oF))
 				{
@@ -406,17 +406,17 @@ void CWaterPoolEditor::OnSavePool()
 				else
 				{
 					oF.close();
-					MessageBox (utf8ToTStr(NLMISC::toString("Unable to init xml stream from file: %s", tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+					MessageBox(nlUtf8ToTStr(NLMISC::toString("Unable to init xml stream from file: %s", NLMISC::tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 				}
 			}
 			else
 			{
-				MessageBox (utf8ToTStr(NLMISC::toString("Unable to open file: %s", tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(NLMISC::toString("Unable to open file: %s", NLMISC::tStrToUtf8(fileDlg.GetPathName()).c_str())), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 			}
 		}
 		catch (const NLMISC::Exception& e)
 		{
-			MessageBox (utf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(nlUtf8ToTStr(e.what()), _T("NeL object viewer"), MB_OK | MB_ICONEXCLAMATION);
 		}
 	}
 	
diff --git a/code/nel/tools/3d/tile_edit/Browse.cpp b/code/nel/tools/3d/tile_edit/Browse.cpp
index a0064456d..b96979d4d 100644
--- a/code/nel/tools/3d/tile_edit/Browse.cpp
+++ b/code/nel/tools/3d/tile_edit/Browse.cpp
@@ -1417,7 +1417,7 @@ void Browse::OnExportBorder()
 			{
 				// Error message
 				std::string tmp = toString("Can't write bitmap %s", tStrToUtf8(pathName).c_str());
-				MessageBox (utf8ToTStr(tmp), _T("Export border"), MB_OK|MB_ICONEXCLAMATION);
+				MessageBox(nlUtf8ToTStr(tmp), _T("Export border"), MB_OK | MB_ICONEXCLAMATION);
 			}
 		}
 	}
@@ -1460,7 +1460,7 @@ void Browse::OnImportBorder()
 		{
 			// Error message
 			std::string tmp = toString("Can't read bitmap %s", tStrToUtf8(pathName).c_str());
-			MessageBox (utf8ToTStr(tmp), _T("Import border"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(nlUtf8ToTStr(tmp), _T("Import border"), MB_OK | MB_ICONEXCLAMATION);
 		}
 
 		// Get pixel
@@ -1484,7 +1484,7 @@ void Browse::OnImportBorder()
 		{
 			// Error message
 			std::string tmp = toString("The bitmap must have a size of 128x128 (%s)", tStrToUtf8(pathName).c_str());
-			MessageBox (utf8ToTStr(tmp), _T("Import border"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(nlUtf8ToTStr(tmp), _T("Import border"), MB_OK | MB_ICONEXCLAMATION);
 		}
 
 		// 256 or 128 ?
diff --git a/code/nel/tools/3d/tile_edit/SelectionTerritoire.cpp b/code/nel/tools/3d/tile_edit/SelectionTerritoire.cpp
index 198fd7942..a8a66e3c9 100644
--- a/code/nel/tools/3d/tile_edit/SelectionTerritoire.cpp
+++ b/code/nel/tools/3d/tile_edit/SelectionTerritoire.cpp
@@ -120,13 +120,13 @@ private:
 	{
 		UpdateData ();
 		TCHAR sTitle[512];
-		_stprintf(sTitle, _T("Tile sets use by %s"), utf8ToTStr(tileBank.getLand(_land)->getName()));
+		_stprintf(sTitle, _T("Tile sets use by %s"), nlUtf8ToTStr(tileBank.getLand(_land)->getName()));
 		SetWindowText (sTitle);
 		for (int i=0; i<tileBank.getTileSetCount(); i++)
 		{
-			m_ctrlCombo.InsertString (-1, utf8ToTStr(tileBank.getTileSet(i)->getName()));
+			m_ctrlCombo.InsertString(-1, nlUtf8ToTStr(tileBank.getTileSet(i)->getName()));
 			if (tileBank.getLand(_land)->isTileSet (tileBank.getTileSet(i)->getName()))
-				m_ctrlList.InsertString (-1, utf8ToTStr(tileBank.getTileSet(i)->getName()));
+				m_ctrlList.InsertString(-1, nlUtf8ToTStr(tileBank.getTileSet(i)->getName()));
 		}
 		UpdateData (FALSE);
 	}
@@ -219,15 +219,15 @@ private:
 	{
 		UpdateData ();
 		TCHAR sTitle[512];
-		_stprintf(sTitle, _T("Children of the tile set %s"), utf8ToTStr(tileBank.getTileSet(_tileSet)->getName()));
+		_stprintf(sTitle, _T("Children of the tile set %s"), nlUtf8ToTStr(tileBank.getTileSet(_tileSet)->getName()));
 		SetWindowText (sTitle);
 		for (int i=0; i<tileBank.getTileSetCount(); i++)
 		{
 			if (i!=_tileSet)
-				m_ctrlCombo.InsertString (-1, utf8ToTStr(tileBank.getTileSet(i)->getName()));
+				m_ctrlCombo.InsertString(-1, nlUtf8ToTStr(tileBank.getTileSet(i)->getName()));
 
 			if (tileBank.getTileSet(_tileSet)->isChild (tileBank.getTileSet(i)->getName()))
-				m_ctrlList.InsertString (-1, utf8ToTStr(tileBank.getTileSet(i)->getName()));
+				m_ctrlList.InsertString(-1, nlUtf8ToTStr(tileBank.getTileSet(i)->getName()));
 		}
 
 		UpdateData (FALSE);
@@ -379,17 +379,17 @@ void SelectionTerritoire::OnSelect()
 			for (i=0; i<tileBank.getLandCount(); i++)
 			{
 				// Add to the list
-				list->AddString(utf8ToTStr(tileBank.getLand(i)->getName()));
+				list->AddString(nlUtf8ToTStr(tileBank.getLand(i)->getName()));
 			}
 
 			for (i=0; i<tileBank.getTileSetCount(); i++)
 			{
 				// Add to the list
-				list2->AddString(utf8ToTStr(tileBank.getTileSet(i)->getName()));
+				list2->AddString(nlUtf8ToTStr(tileBank.getTileSet(i)->getName()));
 			}
 
-			MainFileName = CString(utf8ToTStr(NLMISC::CFile::getFilename(temp)));
-			DefautPath = CString(utf8ToTStr(NLMISC::CFile::getPath(temp)));
+			MainFileName = CString(nlUtf8ToTStr(NLMISC::CFile::getFilename(temp)));
+			DefautPath = CString(nlUtf8ToTStr(NLMISC::CFile::getPath(temp)));
 			
 			MainFileOk = 1;
 			CButton *button = (CButton*)GetDlgItem(IDC_ADD_TERRITOIRE);
@@ -402,7 +402,7 @@ void SelectionTerritoire::OnSelect()
 			button->EnableWindow(true);
 
 			// Change the bouton text path
-			GetDlgItem (IDC_PATH)->SetWindowText (utf8ToTStr(tileBank.getAbsPath()));
+			GetDlgItem(IDC_PATH)->SetWindowText(nlUtf8ToTStr(tileBank.getAbsPath()));
 		}
 	}
 
@@ -468,8 +468,8 @@ void SelectionTerritoire::OnSaveAs()
 		// Create a file name
 		std::string temp = tStrToUtf8(sFile.GetPathName());
 	
-		MainFileName = CString(utf8ToTStr(NLMISC::CFile::getFilename(temp)));
-		DefautPath = CString(utf8ToTStr(NLMISC::CFile::getPath(temp)));
+		MainFileName = CString(nlUtf8ToTStr(NLMISC::CFile::getFilename(temp)));
+		DefautPath = CString(nlUtf8ToTStr(NLMISC::CFile::getPath(temp)));
 	}
 }
 
@@ -582,7 +582,7 @@ void SelectionTerritoire::OnPath()
 									goodPath=false;
 
 									// Make a message
-									_stprintf(msg, _T("Path '%s' can't be found in bitmap '%s'. Continue ?"), path, utf8ToTStr(bitmapPath));
+									_stprintf(msg, _T("Path '%s' can't be found in bitmap '%s'. Continue ?"), path, nlUtf8ToTStr(bitmapPath));
 
 									// Message
 									if (MessageBox (msg, _T("TileEdit"), MB_YESNO|MB_ICONQUESTION)==IDNO)
@@ -611,7 +611,7 @@ void SelectionTerritoire::OnPath()
 							goodPath=false;
 
 							// Make a message
-							_stprintf(msg, _T("Path '%s' can't be found in bitmap '%s'. Continue ?"), path, utf8ToTStr(bitmapPath));
+							_stprintf(msg, _T("Path '%s' can't be found in bitmap '%s'. Continue ?"), path, nlUtf8ToTStr(bitmapPath));
 
 							// Message
 							if (MessageBox (msg, _T("TileEdit"), MB_YESNO|MB_ICONQUESTION)==IDNO)
diff --git a/code/nel/tools/3d/tile_edit/View.cpp b/code/nel/tools/3d/tile_edit/View.cpp
index cf65a527d..fb6cd6890 100644
--- a/code/nel/tools/3d/tile_edit/View.cpp
+++ b/code/nel/tools/3d/tile_edit/View.cpp
@@ -242,7 +242,7 @@ int TileList::setTile128 (int tile, const std::string& name, NL3D::CTile::TBitma
 		{
 			std::string msg = tileBank2.getAbsPath() + troncated + "\nContinue ?";
 
-			return (int)(MessageBox (NULL, utf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO|MB_ICONEXCLAMATION)==IDYES);
+			return (int)(MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO | MB_ICONEXCLAMATION) == IDYES);
 		}
 		else
 		{
@@ -261,7 +261,7 @@ int TileList::setTile128 (int tile, const std::string& name, NL3D::CTile::TBitma
 				static const char* comp[]={"Red", "Green", "Blue", "Alpha", ""};
 				std::string msg = NLMISC::toString("%s\nPixel: %d (%s)\nContinue ?", CTileSet::getErrorMessage (error), pixel, comp[composante]);
 
-				return (int)(MessageBox (NULL, utf8ToTStr(msg), _T("Can't add tile"), MB_YESNO|MB_ICONEXCLAMATION)==IDYES);
+				return (int)(MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't add tile"), MB_YESNO | MB_ICONEXCLAMATION) == IDYES);
 			}
 			else
 			{
@@ -289,7 +289,7 @@ int TileList::setTile128 (int tile, const std::string& name, NL3D::CTile::TBitma
 	{
 		// Error: bitmap not in the absolute path..
 		std::string msg = NLMISC::toString("The bitmap %s is not in the absolute path %s.\nContinue ?", name.c_str(), tileBank2.getAbsPath ().c_str());
-		return (int)(MessageBox (NULL, utf8ToTStr(msg), _T("Load error"), MB_YESNO|MB_ICONEXCLAMATION)==IDYES);
+		return (int)(MessageBox(NULL, nlUtf8ToTStr(msg), _T("Load error"), MB_YESNO | MB_ICONEXCLAMATION) == IDYES);
 	}
 
 	return 1;
@@ -307,7 +307,7 @@ int TileList::setTile256 (int tile, const std::string& name, NL3D::CTile::TBitma
 		if (!loadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height))
 		{
 			std::string msg = tileBank2.getAbsPath() + troncated + "\nContinue ?";
-			return (int)(MessageBox (NULL, utf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO|MB_ICONEXCLAMATION)==IDYES);
+			return (int)(MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO | MB_ICONEXCLAMATION) == IDYES);
 		}
 		else
 		{
@@ -326,7 +326,7 @@ int TileList::setTile256 (int tile, const std::string& name, NL3D::CTile::TBitma
 			{
 				static const char* comp[] = { "Red", "Green", "Blue", "Alpha", "" };
 				std::string msg = NLMISC::toString("%s\nPixel: %d (%s)\nContinue ?", CTileSet::getErrorMessage (error), pixel, comp[composante]);
-				return (int)(MessageBox (NULL, utf8ToTStr(msg), _T("Can't add tile"), MB_YESNO|MB_ICONEXCLAMATION)==IDYES);
+				return (int)(MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't add tile"), MB_YESNO | MB_ICONEXCLAMATION) == IDYES);
 			}
 			else
 			{
@@ -351,7 +351,7 @@ int TileList::setTile256 (int tile, const std::string& name, NL3D::CTile::TBitma
 	{
 		// Error: bitmap not in the absolute path..
 		std::string msg = NLMISC::toString("The bitmap %s is not in the absolute path %s.\nContinue ?", name.c_str(), tileBank2.getAbsPath ().c_str());
-		return (int)(MessageBox (NULL, utf8ToTStr(msg), _T("Load error"), MB_YESNO|MB_ICONEXCLAMATION)==IDYES);
+		return (int)(MessageBox(NULL, nlUtf8ToTStr(msg), _T("Load error"), MB_YESNO | MB_ICONEXCLAMATION) == IDYES);
 	}
 
 	return 1;
@@ -372,7 +372,7 @@ int TileList::setTileTransition (int tile, const std::string& name, NL3D::CTile:
 		if (!loadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height))
 		{
 			std::string msg = tileBank2.getAbsPath() + troncated + "\nContinue ?";
-			return (int)(MessageBox (NULL, utf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO|MB_ICONEXCLAMATION)==IDYES);
+			return (int)(MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO | MB_ICONEXCLAMATION) == IDYES);
 		}
 		else
 		{
@@ -390,7 +390,7 @@ int TileList::setTileTransition (int tile, const std::string& name, NL3D::CTile:
 			{
 				static const char* comp[]={"Red", "Green", "Blue", "Alpha", ""};
 				std::string msg = NLMISC::toString("%s\nPixel: %d (%s)\nContinue ?", CTileSet::getErrorMessage(error), pixel, comp[composante]);
-				return MessageBox (NULL, utf8ToTStr(msg), _T("Can't add tile"), MB_YESNO|MB_ICONEXCLAMATION)==IDYES;
+				return MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't add tile"), MB_YESNO | MB_ICONEXCLAMATION) == IDYES;
 			}
 			else
 			{
@@ -418,7 +418,7 @@ int TileList::setTileTransition (int tile, const std::string& name, NL3D::CTile:
 	{
 		// Error: bitmap not in the absolute path..
 		std::string msg = NLMISC::toString("The bitmap %s is not in the absolute path %s.", name.c_str(), tileBank2.getAbsPath ().c_str());
-		MessageBox (NULL, utf8ToTStr(msg), _T("Load error"), MB_OK|MB_ICONEXCLAMATION);
+		MessageBox(NULL, nlUtf8ToTStr(msg), _T("Load error"), MB_OK | MB_ICONEXCLAMATION);
 	}
 
 	return 1;
@@ -439,7 +439,7 @@ int TileList::setDisplacement (int tile, const std::string& name)
 			if (!_LoadBitmap(tileBank2.getAbsPath() + troncated, &theListDisplacement[tile].BmpInfo, theListDisplacement[tile].Bits, NULL, 0))
 			{
 				std::string msg = tileBank2.getAbsPath() + troncated;
-				MessageBox(NULL, utf8ToTStr(msg), _T("Can't load file"), MB_OK | MB_ICONEXCLAMATION);
+				MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't load file"), MB_OK | MB_ICONEXCLAMATION);
 			}
 			else
 			{
@@ -447,7 +447,7 @@ int TileList::setDisplacement (int tile, const std::string& name)
 				if ((theListDisplacement[tile].BmpInfo.bmiHeader.biWidth!=32)||(-theListDisplacement[tile].BmpInfo.bmiHeader.biHeight!=32))
 				{
 					// Error message
-					MessageBox (NULL, _T("Invalid size: displacement map must be 32x32 8 bits."), utf8ToTStr(troncated),
+					MessageBox(NULL, _T("Invalid size: displacement map must be 32x32 8 bits."), nlUtf8ToTStr(troncated),
 						MB_OK|MB_ICONEXCLAMATION);
 
 					// Free the bitmap
@@ -468,7 +468,7 @@ int TileList::setDisplacement (int tile, const std::string& name)
 	{
 		// Error: bitmap not in the absolute path..
 		std::string msg = NLMISC::toString("The bitmap %s is not in the absolute path %s.", name.c_str(), tileBank2.getAbsPath ().c_str());
-		MessageBox (NULL, utf8ToTStr(msg), _T("Load error"), MB_OK|MB_ICONEXCLAMATION);
+		MessageBox(NULL, nlUtf8ToTStr(msg), _T("Load error"), MB_OK | MB_ICONEXCLAMATION);
 	}
 
 	return 1;
@@ -486,7 +486,7 @@ int TileList::setTileTransitionAlpha (int tile, const std::string& name, int rot
 		if (!loadPic(tileBank2.getAbsPath ()+troncated, tampon, Width, Height))
 		{
 			std::string msg = tileBank2.getAbsPath() + troncated + "\nContinue ?";
-			return MessageBox (NULL, utf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO|MB_ICONEXCLAMATION)==IDYES;
+			return MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't load bitmap."), MB_YESNO | MB_ICONEXCLAMATION) == IDYES;
 		}
 		else
 		{
@@ -528,7 +528,7 @@ int TileList::setTileTransitionAlpha (int tile, const std::string& name, int rot
 
 				msg += "\nContinue ?";
 				
-				return MessageBox (NULL, utf8ToTStr(msg), _T("Can't add tile"), MB_YESNO|MB_ICONEXCLAMATION)==IDYES;
+				return MessageBox(NULL, nlUtf8ToTStr(msg), _T("Can't add tile"), MB_YESNO | MB_ICONEXCLAMATION) == IDYES;
 			}
 			else
 			{
@@ -542,7 +542,7 @@ int TileList::setTileTransitionAlpha (int tile, const std::string& name, int rot
 	{
 		// Error: bitmap not in the absolute path..
 		TCHAR msg[512];
-		_stprintf(msg, _T("The bitmap %s is not in the absolute path %s."), utf8ToTStr(name), utf8ToTStr(tileBank2.getAbsPath ()));
+		_stprintf(msg, _T("The bitmap %s is not in the absolute path %s."), nlUtf8ToTStr(name), nlUtf8ToTStr(tileBank2.getAbsPath()));
 		MessageBox (NULL, msg, _T("Load error"), MB_OK|MB_ICONEXCLAMATION);
 	}
 
@@ -681,7 +681,7 @@ bool TileInfo::Load (int index, std::vector<NLMISC::CBGRA>* Alpha)
 		if (!_LoadBitmap(tileBank2.getAbsPath() + getRelativeFileName (CTile::diffuse, index), &BmpInfo, Bits, Alpha, 0))
 		{
 			bRes=false;
-			MessageBox (NULL, utf8ToTStr(tileBank2.getAbsPath() + getRelativeFileName (CTile::diffuse, index)), _T("Can't load file"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(NULL, nlUtf8ToTStr(tileBank2.getAbsPath() + getRelativeFileName(CTile::diffuse, index)), _T("Can't load file"), MB_OK | MB_ICONEXCLAMATION);
 		}
 		else
 			loaded=1;
@@ -691,7 +691,7 @@ bool TileInfo::Load (int index, std::vector<NLMISC::CBGRA>* Alpha)
 		if (!_LoadBitmap(tileBank2.getAbsPath() + getRelativeFileName (CTile::additive, index), &nightBmpInfo, nightBits, Alpha, 0))
 		{
 			bRes=false;
-			MessageBox (NULL, utf8ToTStr(tileBank2.getAbsPath() + getRelativeFileName (CTile::additive, index)), _T("Can't load file"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(NULL, nlUtf8ToTStr(tileBank2.getAbsPath() + getRelativeFileName(CTile::additive, index)), _T("Can't load file"), MB_OK | MB_ICONEXCLAMATION);
 		}
 		else
 			nightLoaded=1;
@@ -702,7 +702,7 @@ bool TileInfo::Load (int index, std::vector<NLMISC::CBGRA>* Alpha)
 			tileBank2.getTile (index)->getRotAlpha ()))
 		{
 			bRes=false;
-			MessageBox (NULL, utf8ToTStr(tileBank2.getAbsPath() + getRelativeFileName (CTile::alpha, index)), _T("Can't load file"), MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(NULL, nlUtf8ToTStr(tileBank2.getAbsPath() + getRelativeFileName(CTile::alpha, index)), _T("Can't load file"), MB_OK | MB_ICONEXCLAMATION);
 		}
 		else
 			alphaLoaded=1;
@@ -1145,7 +1145,7 @@ void CTView::OnDropFiles(HDROP hDropInfo)
 			case 0:
 				{
 					int index=InfoList.addTile128 ();
-					if (InfoList.setTile128 (index, tStrToUtf8(FileName), Texture==1?CTile::diffuse:(Texture==2?CTile::additive:CTile::alpha)))
+					if (InfoList.setTile128 (index, NLMISC::tStrToUtf8(FileName), Texture==1?CTile::diffuse:(Texture==2?CTile::additive:CTile::alpha)))
 					{
 						tilelist::iterator it = InfoList.GetLast(parent->m_128x128);
 						it--;
@@ -1159,7 +1159,7 @@ void CTView::OnDropFiles(HDROP hDropInfo)
 			case 1:
 				{
 					int index=InfoList.addTile256 ();
-					if (InfoList.setTile256 (index, tStrToUtf8(FileName), Texture==1?CTile::diffuse:(Texture==2?CTile::additive:CTile::alpha)))
+				    if (InfoList.setTile256(index, NLMISC::tStrToUtf8(FileName), Texture == 1 ? CTile::diffuse : (Texture == 2 ? CTile::additive : CTile::alpha)))
 					{
 						tilelist::iterator it = InfoList.GetLast(parent->m_128x128);
 						it--;
@@ -1534,7 +1534,7 @@ LRESULT CTView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
 		else if ((id==ID_MENU_ADD)||(id==ID_MENU_REPLACE))
 		{
 			_chdir (LastPath.c_str());
-			CFileDialog load(true, NULL, utf8ToTStr(LastPath), OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, _T("PNG Bitmap (*.png)|*.png|Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||"), NULL);
+			CFileDialog load(true, NULL, nlUtf8ToTStr(LastPath), OFN_ENABLESIZING | OFN_ALLOWMULTISELECT, _T("PNG Bitmap (*.png)|*.png|Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||"), NULL);
 			load.m_ofn.lpstrFile = new TCHAR[10000]; // buffer contains filenames list
 			load.m_ofn.lpstrFile[0] = 0;
 			// with 10 KB we should be large enough...
@@ -1551,12 +1551,12 @@ LRESULT CTView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
 				{
 					CString str = load.GetNextPathName(p);
 
-					LastPath = NLMISC::CFile::getPath(tStrToUtf8(str));
+					LastPath = NLMISC::CFile::getPath(NLMISC::tStrToUtf8(str));
 
 					if (!str.IsEmpty())
 					{
 						int index=0;
-						std::string pathname = tStrToUtf8(str);
+						std::string pathname = NLMISC::tStrToUtf8(str);
 
 						// Add mode, to the end of the list
 						if (id==ID_MENU_ADD)
diff --git a/code/nel/tools/3d/tile_edit/choose_veget_set.cpp b/code/nel/tools/3d/tile_edit/choose_veget_set.cpp
index e1ccf4f4f..a0256bd89 100644
--- a/code/nel/tools/3d/tile_edit/choose_veget_set.cpp
+++ b/code/nel/tools/3d/tile_edit/choose_veget_set.cpp
@@ -68,8 +68,8 @@ void CChooseVegetSet::OnBrowse()
 	if (dialog.DoModal() == IDOK)
 	{
 		// Get the file name
-		FileName = tStrToUtf8(dialog.GetFileName ());
-		Name.SetWindowText (utf8ToTStr(FileName));
+		FileName = NLMISC::tStrToUtf8(dialog.GetFileName());
+		Name.SetWindowText(nlUtf8ToTStr(FileName));
 	}
 }
 
@@ -78,7 +78,7 @@ BOOL CChooseVegetSet::OnInitDialog()
 	CDialog::OnInitDialog();
 	
 	if (!FileName.empty())
-		Name.SetWindowText (utf8ToTStr(FileName));
+		Name.SetWindowText(nlUtf8ToTStr(FileName));
 	else
 		Name.SetWindowText (_T("Browse..."));
 

From 096e5e955e75f05858572344b68483aa9f4d23dd Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 06:46:01 +0800
Subject: [PATCH 45/75] Cleaning up unicode conversion and fixing 64bit issues

---
 .../tools/misc/data_mirror/data_mirrorDlg.cpp | 50 +++++++++----------
 .../misc/log_analyser/PlugInSelector.cpp      |  4 +-
 .../tools/misc/log_analyser/ViewDialog.cpp    | 49 +++++++++---------
 .../misc/log_analyser/log_analyserDlg.cpp     | 50 +++++++++----------
 .../nel/tools/misc/words_dic/words_dicDlg.cpp |  4 +-
 5 files changed, 79 insertions(+), 78 deletions(-)

diff --git a/code/nel/tools/misc/data_mirror/data_mirrorDlg.cpp b/code/nel/tools/misc/data_mirror/data_mirrorDlg.cpp
index 4fb771d86..602e805b2 100644
--- a/code/nel/tools/misc/data_mirror/data_mirrorDlg.cpp
+++ b/code/nel/tools/misc/data_mirror/data_mirrorDlg.cpp
@@ -280,8 +280,8 @@ void CData_mirrorDlg::updateList ()
 	{
 		// Add the items
 		const CEntryFile &entry = *ite;
-		uint nItem = List.InsertItem (0, utf8ToTStr(entry.Strings[CEntryFile::Path]), entry.Image);
-		List.SetItemData (nItem, DWORD(new std::list<CEntryFile>::iterator (ite)));
+		uint nItem = List.InsertItem(0, nlUtf8ToTStr(entry.Strings[CEntryFile::Path]), entry.Image);
+		List.SetItemData (nItem, DWORD_PTR(new std::list<CEntryFile>::iterator (ite)));
 
 		// Sub string
 		subString = 1;
@@ -289,25 +289,25 @@ void CData_mirrorDlg::updateList ()
 		// Add the sizes
 		if (ModifiedFilter != Removed)
 		{
-			List.SetItemText (nItem, subString++, utf8ToTStr(entry.Strings[CEntryFile::NewSize]));
+			List.SetItemText(nItem, subString++, nlUtf8ToTStr(entry.Strings[CEntryFile::NewSize]));
 		}
 		if (ModifiedFilter != Added)
 		{
-			List.SetItemText (nItem, subString++, utf8ToTStr(entry.Strings[CEntryFile::OldSize]));
+			List.SetItemText(nItem, subString++, nlUtf8ToTStr(entry.Strings[CEntryFile::OldSize]));
 		}
 
 		// Add the dates
 		if (ModifiedFilter != Removed)
 		{
-			List.SetItemText (nItem, subString++, utf8ToTStr(entry.Strings[CEntryFile::NewDate]));
+			List.SetItemText(nItem, subString++, nlUtf8ToTStr(entry.Strings[CEntryFile::NewDate]));
 		}
 		if (ModifiedFilter != Added)
 		{
-			List.SetItemText (nItem, subString++, utf8ToTStr(entry.Strings[CEntryFile::OldDate]));
+			List.SetItemText(nItem, subString++, nlUtf8ToTStr(entry.Strings[CEntryFile::OldDate]));
 		}
 
 		// Add the type
-		List.SetItemText (nItem, subString++, utf8ToTStr(entry.Strings[CEntryFile::Type]));
+		List.SetItemText(nItem, subString++, nlUtf8ToTStr(entry.Strings[CEntryFile::Type]));
 
 		// Next item
 		ite++;
@@ -410,7 +410,7 @@ void createDirectory (const string &dir)
 
 bool setFileTime(const std::string &filename, const FILETIME &result)
 {
-	HANDLE handle = CreateFile (utf8ToTStr(filename), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	HANDLE handle = CreateFile(nlUtf8ToTStr(filename), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 	if (handle)
 	{
 		SetFileTime (handle, NULL, NULL, &result);
@@ -450,18 +450,18 @@ void CData_mirrorDlg::OnOK()
 	{
 		// Copy it
 		const string &itemText = modifiedList[i];
-		string source = MainDirectory+itemText;
-		string dest = MirrorDirectory+itemText;
-	
-		progress.DisplayString = "Copy \"" + source + "\" to \"" + dest + "\"";
-		progress.progress (float(currentFile++)/(float(totalCount)));
+		string source = MainDirectory + itemText;
+		string dest = MirrorDirectory + itemText;
 
-		string directory = NLMISC::CFile::getPath (dest);
-		createDirectory (directory.c_str ());
-		if (!CopyFile (source.c_str (), dest.c_str (), FALSE))
+		progress.DisplayString = "Copy \"" + source + "\" to \"" + dest + "\"";
+		progress.progress(float(currentFile++) / (float(totalCount)));
+
+		string directory = NLMISC::CFile::getPath(dest);
+		createDirectory(directory.c_str());
+		if (!CopyFile(nlUtf8ToTStr(source), nlUtf8ToTStr(dest), FALSE))
 		{
-			MessageBox (("Can't copy file "+source+" in file "+dest).c_str (), _T("NeL Data Mirror"),
-				MB_OK|MB_ICONEXCLAMATION);
+			MessageBox(nlUtf8ToTStr("Can't copy file " + source + " in file " + dest), _T("NeL Data Mirror"),
+			    MB_OK | MB_ICONEXCLAMATION);
 			success = false;
 		}
 		else
@@ -497,9 +497,9 @@ void CData_mirrorDlg::OnOK()
 		progress.progress (float(currentFile++)/(float(totalCount)));
 		
 		createDirectory (directory.c_str ());
-		if (!CopyFile (source.c_str (), dest.c_str (), FALSE))
+		if (!CopyFile(nlUtf8ToTStr(source), nlUtf8ToTStr(dest), FALSE))
 		{
-			MessageBox (("Can't copy file "+source+" in file "+dest).c_str (), _T("NeL Data Mirror"),
+			MessageBox(nlUtf8ToTStr("Can't copy file " + source + " in file " + dest), _T("NeL Data Mirror"),
 				MB_OK|MB_ICONEXCLAMATION);
 			success = false;
 		}
@@ -532,9 +532,9 @@ void CData_mirrorDlg::OnOK()
 		progress.DisplayString = "Delete \"" + dest + "\"";
 		progress.progress (float(currentFile++)/(float(totalCount)));
 
-		if (!DeleteFile (dest.c_str ()))
+		if (!DeleteFile(nlUtf8ToTStr(dest)))
 		{
-			MessageBox (("Can't delete the file "+dest).c_str (), _T("NeL Data Mirror"),
+			MessageBox(nlUtf8ToTStr("Can't delete the file " + dest), _T("NeL Data Mirror"),
 				MB_OK|MB_ICONEXCLAMATION);
 			success = false;
 		}
@@ -596,7 +596,7 @@ void CData_mirrorDlg::OnSize(UINT nType, int cx, int cy)
 
 bool getFileTime (const std::string &filename, FILETIME &result)
 {
-	HANDLE handle = CreateFile (utf8ToTStr(filename), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	HANDLE handle = CreateFile(nlUtf8ToTStr(filename), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 	if (handle)
 	{
 		FILETIME res0;
@@ -700,7 +700,7 @@ void CData_mirrorDlg::buildSourceFiles ()
 			{
 				FILETIME time;
 				getFileTime (mainFile, time);
-				addEntry (Added, str, time, time);
+				addEntry (Added, str.c_str(), time, time);
 			}
 		}
 	}
@@ -812,7 +812,7 @@ void CData_mirrorDlg::addEntry (uint where, const char *filename, FILETIME &newD
 		// Get the image
 		SHFILEINFO     sfi;
 		TCHAR winName[512];
-		_tcscpy (winName, utf8ToTStr(aFilename));
+		_tcscpy(winName, nlUtf8ToTStr(aFilename));
 		TCHAR *ptr = winName;
 		while (*ptr)
 		{
diff --git a/code/nel/tools/misc/log_analyser/PlugInSelector.cpp b/code/nel/tools/misc/log_analyser/PlugInSelector.cpp
index 120ceacaf..abc5ec03c 100644
--- a/code/nel/tools/misc/log_analyser/PlugInSelector.cpp
+++ b/code/nel/tools/misc/log_analyser/PlugInSelector.cpp
@@ -147,8 +147,8 @@ void CPlugInSelector::OnSelchangeList1()
 		AfxMessageBox( _T("Can't find function getInfoString in dll") );
 		return;
 	}
-	GetDlgItem( IDC_GROUP_INFO )->SetWindowText( utf8ToTStr(getFilename(tStrToUtf8(dllName))) );
-	GetDlgItem( IDC_PLUGIN_INFO )->SetWindowText(utf8ToTStr(infoFunc()) );
+	GetDlgItem(IDC_GROUP_INFO)->SetWindowText(nlUtf8ToTStr(getFilename(NLMISC::tStrToUtf8(dllName))));
+	GetDlgItem(IDC_PLUGIN_INFO)->SetWindowText(nlUtf8ToTStr(infoFunc()));
 
 	// Prepare analyse func
 	AnalyseFunc = (TAnalyseFunc)GetProcAddress( LibInst, "doAnalyse" );
diff --git a/code/nel/tools/misc/log_analyser/ViewDialog.cpp b/code/nel/tools/misc/log_analyser/ViewDialog.cpp
index cdc38ed08..5710795bf 100644
--- a/code/nel/tools/misc/log_analyser/ViewDialog.cpp
+++ b/code/nel/tools/misc/log_analyser/ViewDialog.cpp
@@ -359,7 +359,7 @@ void		CViewDialog::getBookmarksAbsoluteLines( vector<int>& bookmarksAbsoluteLine
 
 		NLMISC::CIFile ifs;
 
-		if (ifs.open(tStrToUtf8(filename)))
+		if (ifs.open(NLMISC::tStrToUtf8(filename)))
 		{
 			char line [1024];
 
@@ -370,7 +370,7 @@ void		CViewDialog::getBookmarksAbsoluteLines( vector<int>& bookmarksAbsoluteLine
 				if ( SessionDatePassed )
 				{
 					// Stop if the session is finished
-					if ( (! LogSessionStartDate.IsEmpty()) && (strstr( line, tStrToUtf8(LogDateString).c_str())) )
+					if ( (! LogSessionStartDate.IsEmpty()) && (strstr( line, nlTStrToUtf8(LogDateString))) )
 					{
 						return;
 					}
@@ -394,7 +394,7 @@ void		CViewDialog::getBookmarksAbsoluteLines( vector<int>& bookmarksAbsoluteLine
 				else
 				{
 					// Look for the session beginning
-					if ( strstr( line, tStrToUtf8(LogSessionStartDate).c_str()) != NULL )
+					if ( strstr( line, nlTStrToUtf8(LogSessionStartDate)) != NULL )
 					{
 						SessionDatePassed = true;
 					}
@@ -466,7 +466,7 @@ std::string		CViewDialog::corruptedLinesString( const std::vector<unsigned int>&
 		vector<unsigned int>::const_iterator ivc;
 		for ( ivc=corruptedLines.begin(); ivc!=corruptedLines.end(); ++ivc )
 		{
-			res += NLMISC::toString("\r\n   line %u : %s...", *ivc, tStrToUtf8(Buffer[*ivc].Left(20)).c_str());
+			res += NLMISC::toString("\r\n   line %u : %s...", *ivc, NLMISC::tStrToUtf8(Buffer[*ivc].Left(20)).c_str());
 		}
 		HasCorruptedLines = true;
 	}
@@ -484,7 +484,7 @@ void		CViewDialog::loadFileOrSeries( const vector<int>& bookmarksAbsoluteLines )
 	if ( LogSessionStartDate.IsEmpty() )
 		actualFilenames += ":\r\n";
 	else
-		actualFilenames += " for Session of " + tStrToUtf8(LogSessionStartDate) + ":\r\n";
+		actualFilenames += " for Session of " + NLMISC::tStrToUtf8(LogSessionStartDate) + ":\r\n";
 	bool corruptionDetectionEnabled = (((CButton*)(((CLog_analyserDlg*)GetParent())->GetDlgItem( IDC_DetectCorruptedLines )))->GetCheck() == 1);
 	HasCorruptedLines = false;
 	vector<unsigned int> corruptedLines;
@@ -505,9 +505,9 @@ void		CViewDialog::loadFileOrSeries( const vector<int>& bookmarksAbsoluteLines )
 				if ( SessionDatePassed )
 				{
 					// Stop if the session is finished
-					if ( (! LogSessionStartDate.IsEmpty()) && (strstr( line, LogDateString )) )
+					if ( (! LogSessionStartDate.IsEmpty()) && (strstr( line, nlTStrToUtf8(LogDateString) )) )
 					{
-						actualFilenames += string(filename) + corruptedLinesString( corruptedLines ) + "\r\n";
+						actualFilenames += NLMISC::tStrToUtf8(filename) + corruptedLinesString(corruptedLines) + "\r\n";
 						corruptedLines.clear();
 						goto endOfLoading;
 					}
@@ -540,7 +540,7 @@ void		CViewDialog::loadFileOrSeries( const vector<int>& bookmarksAbsoluteLines )
 				else
 				{
 					// Look for the session beginning
-					if ( strstr( line, LogSessionStartDate ) != NULL )
+					if ( strstr( line, nlTStrToUtf8(LogSessionStartDate) ) != NULL )
 					{
 						SessionDatePassed = true;
 					}
@@ -549,15 +549,15 @@ void		CViewDialog::loadFileOrSeries( const vector<int>& bookmarksAbsoluteLines )
 
 			if ( SessionDatePassed )
 			{
-				actualFilenames += string(filename) + corruptedLinesString( corruptedLines ) + "\r\n";
+				actualFilenames += NLMISC::tStrToUtf8(filename) + corruptedLinesString(corruptedLines) + "\r\n";
 				corruptedLines.clear();
 			}
 		}
 		else
 		{
 			CString s;
-			s.Format( "<Cannot open file %s>\r\n", filename );
-			actualFilenames += s;
+			s.Format(_T( "<Cannot open file %s>\r\n"), filename);
+			actualFilenames += NLMISC::tStrToUtf8(s);
 		}
 	}
 
@@ -598,7 +598,7 @@ bool		CViewDialog::passFilter( const char *text, const std::vector<CString>& pos
 	// 1. Positive filter
 	for ( ilf=posFilter.begin(); ilf!=posFilter.end(); ++ilf )
 	{
-		found = ( strstr( text, *ilf ) != NULL );
+		found = (strstr(text, nlTStrToUtf8(*ilf)) != NULL);
 		if ( found )
 		{
 			yes = true; // positive filter passed (no need to check another one)
@@ -614,7 +614,7 @@ bool		CViewDialog::passFilter( const char *text, const std::vector<CString>& pos
 	// 2. Negative filter
 	for ( ilf=negFilter.begin(); ilf!=negFilter.end(); ++ilf )
 	{
-		found = ( strstr( text, *ilf ) != NULL );
+		found = (strstr(text, nlTStrToUtf8(*ilf)) != NULL);
 		if ( found )
 		{
 			return false; // negative filter not passed (no need to check another one)
@@ -665,14 +665,15 @@ void		CViewDialog::reloadTrace()
 			if ( SessionDatePassed )
 			{
 				// Stop if the session is finished
-				if ( (! LogSessionStartDate.IsEmpty()) && (strstr( line, LogDateString )) )
+				if ((!LogSessionStartDate.IsEmpty()) && (strstr(line, nlTStrToUtf8(LogDateString))))
 					break;
 
 				// Read if it's a TRACE
 				char *pc = strstr( line, "TRACE" );
 				if ( pc != NULL )
 				{
-					if ( PosFilter.empty() || (strncmp( pc-PosFilter[0].GetLength(), PosFilter[0], PosFilter[0].GetLength() ) == 0) )
+					std::string tposFilter0 = NLMISC::tStrToUtf8(PosFilter[0]);
+					if (PosFilter.empty() || (strncmp(pc - PosFilter[0].GetLength(), tposFilter0.c_str(), tposFilter0.size()) == 0))
 					{
 						((CLog_analyserDlg*)GetParent())->insertTraceLine( Index, pc+6 );
 					}
@@ -681,7 +682,7 @@ void		CViewDialog::reloadTrace()
 			else
 			{
 				// Look for the session beginning
-				if ( strstr( line, LogSessionStartDate ) != NULL )
+				if (strstr(line, nlTStrToUtf8(LogSessionStartDate)) != NULL)
 				{
 					SessionDatePassed = true;
 				}
@@ -974,7 +975,7 @@ BOOL CViewDialog::OnInitDialog()
 	CDialog::OnInitDialog();
 	
 	m_ListCtrl.GetHeaderCtrl()->ModifyStyle( 0, HDS_HIDDEN );
-	m_ListCtrl.InsertColumn( 0, "" );
+	m_ListCtrl.InsertColumn(0, _T(""));
 	m_ListCtrl.setViewDialog( this );
 	m_ListCtrl.initIt();
 
@@ -998,11 +999,11 @@ COLORREF CViewDialog::getTextColorForLine( int index, bool selected )
 		return ::GetSysColor(COLOR_HIGHLIGHTTEXT);
 	else
 	{
-		if ( Buffer[index].Find( "DBG" ) != -1 )
+		if ( Buffer[index].Find( _T("DBG") ) != -1 )
 			return RGB(0x80,0x80,0x80);
-		else if ( Buffer[index].Find( "WRN" ) != -1 )
+		else if ( Buffer[index].Find( _T("WRN") ) != -1 )
 			return RGB(0x80,0,0);
-		else if ( (Buffer[index].Find( "ERR" ) != -1) || (Buffer[index].Find( "AST" ) != -1) )
+		else if ( (Buffer[index].Find( _T("ERR") ) != -1) || (Buffer[index].Find( _T("AST") ) != -1) )
 			return RGB(0xFF,0,0);
 		else // INF and others
 			return RGB(0,0,0);
@@ -1038,7 +1039,7 @@ void formatLogStr( CString& str, bool displayHeaders )
 {
 	if ( ! displayHeaders )
 	{
-		int pos = str.Find( " : " );
+		int pos = str.Find( _T(" : ") );
 		if ( pos != -1 )
 		{
 			str.Delete( 0, pos + 3 );
@@ -1156,7 +1157,7 @@ afx_msg LRESULT CViewDialog::OnFindReplace(WPARAM wParam, LPARAM lParam)
 					//BeginFindIndex = getSelectionIndex()+1;
 					//displayString();
 					CString s;
-					s.Format( "Found '%s' (downwards from line %d) at line %d:\r\n%s", FindStr, BeginFindIndex, lineIndex, Buffer[lineIndex] );
+					s.Format( _T("Found '%s' (downwards from line %d) at line %d:\r\n%s"), FindStr, BeginFindIndex, lineIndex, Buffer[lineIndex] );
 					((CLog_analyserDlg*)GetParent())->displayCurrentLine( s );
 					((CLog_analyserDlg*)GetParent())->selectText( 1, matchPos, FindStr.GetLength() );
 					//BeginFindIndex = lineIndex+1;
@@ -1176,7 +1177,7 @@ afx_msg LRESULT CViewDialog::OnFindReplace(WPARAM wParam, LPARAM lParam)
 					//BeginFindIndex = getSelectionIndex()-1;
 					//displayString();
 					CString s;
-					s.Format( "Found '%s' (upwards from line %d) at line %d:\r\n%s", FindStr, BeginFindIndex, lineIndex, Buffer[lineIndex] );
+					s.Format( _T("Found '%s' (upwards from line %d) at line %d:\r\n%s"), FindStr, BeginFindIndex, lineIndex, Buffer[lineIndex] );
 					((CLog_analyserDlg*)GetParent())->displayCurrentLine( s );
 					((CLog_analyserDlg*)GetParent())->selectText( 1, matchPos, FindStr.GetLength() );
 					//BeginFindIndex = lineIndex-1;
@@ -1185,7 +1186,7 @@ afx_msg LRESULT CViewDialog::OnFindReplace(WPARAM wParam, LPARAM lParam)
 			}
 		}
 		CString s;
-		s.Format( "Not found (%s from line %d)", FindDialog->SearchDown() ? "downwards" : "upwards", BeginFindIndex );
+		s.Format( _T("Not found (%s from line %d)"), FindDialog->SearchDown() ? _T("downwards") : _T("upwards"), BeginFindIndex );
 		AfxMessageBox( s );
 		//BeginFindIndex = 0;
 		return 0;
diff --git a/code/nel/tools/misc/log_analyser/log_analyserDlg.cpp b/code/nel/tools/misc/log_analyser/log_analyserDlg.cpp
index e23fd2bd9..afc73018f 100644
--- a/code/nel/tools/misc/log_analyser/log_analyserDlg.cpp
+++ b/code/nel/tools/misc/log_analyser/log_analyserDlg.cpp
@@ -59,7 +59,7 @@ afx_msg void CLAEdit::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
 				int start, end;
 				GetSel( start, end );
 				str = str.Mid( start, end-start );
-				int lineNum = atoi( str );
+				int lineNum = atoi(nlTStrToUtf8(str));
 				if ( ! ((lineNum != 0) || (str == "0")) )
 					break;
 
@@ -203,7 +203,7 @@ BOOL CLog_analyserDlg::OnInitDialog()
 	SetIcon(m_hIcon, FALSE);		// Set small icon
 
 	// Add files given in command-line
-	string cmdLine = string(theApp.m_lpCmdLine);
+	string cmdLine = NLMISC::tStrToUtf8(theApp.m_lpCmdLine);
 	vector<CString> v;
 	/*int pos = cmdLine.find_first_of(' '); // TODO: handle "" with blank characters
 	while ( pos != string::npos )
@@ -285,9 +285,9 @@ void CLog_analyserDlg::OnDropFiles( HDROP hDropInfo )
 		DragQueryFile( hDropInfo, i, filename.GetBufferSetLength( 200 ), 200 );
 
 		// Plug-in DLL or log file
-		if ( getFileExtension( string(filename) ) == "dll" )
+		if ( getFileExtension( NLMISC::tStrToUtf8(filename) ) == "dll" )
 		{
-			if ( addPlugIn( string(filename) ) )
+			if (addPlugIn(NLMISC::tStrToUtf8(filename)))
 				AfxMessageBox( CString("Plugin added: ") + filename );
 			else
 				AfxMessageBox( CString("Plugin already registered: ") + filename );
@@ -310,16 +310,16 @@ bool CLog_analyserDlg::addPlugIn( const std::string& dllName )
 {
 	int i = 0;
 	char pluginN [10] = "Plugin0";
-	CString pn = theApp.GetProfileString( _T(""), _T(pluginN) );
+	CString pn = theApp.GetProfileString(_T(""), nlUtf8ToTStr(pluginN));
 	while ( ! pn.IsEmpty() )
 	{
-		if ( string(pn) == dllName )
+		if (NLMISC::tStrToUtf8(pn) == dllName)
 			return false; // already registered
 		++i;
 		smprintf( pluginN, 10, "Plugin%d", i );
-		pn = theApp.GetProfileString( _T(""), _T(pluginN) );
+		pn = theApp.GetProfileString(_T(""), nlUtf8ToTStr(pluginN));
 	}
-	theApp.WriteProfileString( _T(""), _T(pluginN), dllName.c_str() );
+	theApp.WriteProfileString(_T(""), nlUtf8ToTStr(pluginN), nlUtf8ToTStr(dllName));
 	Plugins.push_back( dllName.c_str() );
 	return true;
 }
@@ -342,7 +342,7 @@ void CLog_analyserDlg::loadPluginConfiguration()
 		Plugins.push_back( pn );
 		++i;
 		smprintf( pluginN, 10, "Plugin%d", i );
-		pn = theApp.GetProfileString( _T(""), _T(pluginN) );
+		pn = theApp.GetProfileString( _T(""), nlUtf8ToTStr(pluginN) );
 	}
 }
 
@@ -373,7 +373,7 @@ void CLog_analyserDlg::addView( std::vector<CString>& pathNames )
 {
 	if ( pathNames.empty() )
 	{
-		CFileDialog openDialog( true, NULL, "log.log", OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT, "Log files (*.log)|*.log|All files|*.*||", this );
+		CFileDialog openDialog( true, NULL, _T("log.log"), OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT, _T("Log files (*.log)|*.log|All files|*.*||"), this );
 		CString filenameList;
 		openDialog.m_ofn.lpstrFile = filenameList.GetBufferSetLength( 8192 );
 		openDialog.m_ofn.nMaxFile = 8192;
@@ -402,7 +402,7 @@ void CLog_analyserDlg::addView( std::vector<CString>& pathNames )
 		for ( i=0; i!=pathNames.size(); ++i )
 		{
 			// Ensure that a log file without number comes *after* the ones with a number
-			string name = string(pathNames[i]);
+			string name = NLMISC::tStrToUtf8(pathNames[i]);
 			string::size_type dotpos = name.find_last_of('.');
 			if ( (dotpos!=string::npos) && (dotpos > 2) )
 			{
@@ -417,7 +417,7 @@ void CLog_analyserDlg::addView( std::vector<CString>& pathNames )
 		for ( i=0; i!=pathNames.size(); ++i )
 		{
 			// Set the original names back
-			string name = pathNames[i];
+			string name = NLMISC::tStrToUtf8(pathNames[i]);
 			string::size_type tokenpos = name.find( "ZZZ." );
 			if ( tokenpos != string::npos )
 			{
@@ -434,7 +434,7 @@ void CLog_analyserDlg::addView( std::vector<CString>& pathNames )
 	else
 		names += "Loading files:\r\n";
 	for ( i=0; i!=pathNames.size(); ++i )
-		names += string(pathNames[i]) + "\r\n";
+		names += NLMISC::tStrToUtf8(pathNames[i]) + "\r\n";
 	displayCurrentLine( names.c_str() );
 	
 	// Add view and browse sessions if needed
@@ -457,7 +457,7 @@ void CLog_analyserDlg::addView( std::vector<CString>& pathNames )
  */
 void CLog_analyserDlg::OnAddtraceview() 
 {
-	CFileDialog openDialog( true, NULL, "log.log", OFN_HIDEREADONLY, "Log files (*.log)|*.log|All files|*.*||", this );
+	CFileDialog openDialog( true, NULL, _T("log.log"), OFN_HIDEREADONLY, _T("Log files (*.log)|*.log|All files|*.*||"), this );
 	if ( openDialog.DoModal() == IDOK )
 	{
 		vector<CString> pathNames;
@@ -534,7 +534,7 @@ CViewDialog *CLog_analyserDlg::onAddCommon( const vector<CString>& filenames )
 				while ( ! ifs.eof() )
 				{
 					ifs.getline( line, 1024 );
-					if ( strstr( line, LogDateString ) != NULL )
+					if ( strstr( line, nlTStrToUtf8(LogDateString) ) != NULL )
 					{
 						LogSessionsDialog.addLogSession( line );
 						++nbsessions;
@@ -554,19 +554,19 @@ CViewDialog *CLog_analyserDlg::onAddCommon( const vector<CString>& filenames )
 		case 1:
 			{
 			// 1 'Log Starting' => no choice if it's at the beginning (1st line, or 2nd line with blank 1st)
-			ifstream ifs( view->Filenames[0] ); // 1 session => ! Filename.empty()
-			char line [1024];
-			ifs.getline( line, 1024 );
-			if ( ! ifs.fail() )
+			ifstream ifs(view->Filenames[0]); // 1 session => ! Filename.empty()
+			char line[1024];
+			ifs.getline(line, 1024);
+			if (!ifs.fail())
 			{
-				if ( strstr( line, LogDateString ) != NULL )
+				if (strstr(line, nlTStrToUtf8(LogDateString)) != NULL)
 					needToChooseSession = false;
 				else if ( string(line).empty() )
 				{
-					if ( ! ifs.fail() )
+					if (!ifs.fail())
 					{
-						ifs.getline( line, 1024 );
-						needToChooseSession = (strstr( line, LogDateString ) == NULL);
+						ifs.getline(line, 1024);
+						needToChooseSession = (strstr(line, nlTStrToUtf8(LogDateString)) == NULL);
 					}
 					else
 						needToChooseSession = true;
@@ -575,7 +575,7 @@ CViewDialog *CLog_analyserDlg::onAddCommon( const vector<CString>& filenames )
 			else
 				needToChooseSession = true;
 			}
-			break;
+		    break;
 		default:
 			// Several 'Log Starting' => always choice
 			needToChooseSession = true;
@@ -620,7 +620,7 @@ void CLog_analyserDlg::getLogSeries( const CString& filenameStr, std::vector<CSt
 {
 	if ( isLogSeriesEnabled() )
 	{
-		string filename = tStrToUtf8(filenameStr);
+		string filename = NLMISC::tStrToUtf8(filenameStr);
 		unsigned int dotpos = filename.find_last_of ('.');
 		if ( dotpos != string::npos )
 		{
diff --git a/code/nel/tools/misc/words_dic/words_dicDlg.cpp b/code/nel/tools/misc/words_dic/words_dicDlg.cpp
index f161e22e5..cac6c20b2 100644
--- a/code/nel/tools/misc/words_dic/words_dicDlg.cpp
+++ b/code/nel/tools/misc/words_dic/words_dicDlg.cpp
@@ -176,7 +176,7 @@ void CWords_dicDlg::lookUp( const CString& inputStr )
 			const CSString& res = (*ivs);
 			if ( showAll || (res.find( "lvl" ) == string::npos) )
 			{
-				m_Results.AddString( utf8ToTStr(res) );
+				m_Results.AddString(nlUtf8ToTStr(res));
 			}
 			else
 				lvlRemoved = true;
@@ -234,7 +234,7 @@ void CWords_dicDlg::OnFileList()
 	const vector<string>& fileList = Dico.getFileList();
 	for ( vector<string>::const_iterator ifl=fileList.begin(); ifl!=fileList.end(); ++ifl )
 	{
-		m_Results.AddString( utf8ToTStr(*ifl) );
+		m_Results.AddString( nlUtf8ToTStr(*ifl) );
 	}
 }
 

From 35c59359df6f48bc148ad9541f9f5da7b878c347 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 06:53:46 +0800
Subject: [PATCH 46/75] Fix build project. Can't build shard sheet builder
 without server shared library

---
 code/ryzom/tools/CMakeLists.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/code/ryzom/tools/CMakeLists.txt b/code/ryzom/tools/CMakeLists.txt
index 9061d1e0f..789ec684f 100644
--- a/code/ryzom/tools/CMakeLists.txt
+++ b/code/ryzom/tools/CMakeLists.txt
@@ -17,7 +17,10 @@ IF(WITH_RYZOM_TOOLS)
     ADD_SUBDIRECTORY(patch_gen)
 
     IF(WIN32)
-      ADD_SUBDIRECTORY(sheets_packer_shard)
+      FIND_PACKAGE(MySQL)
+      IF(MYSQL_FOUND)
+        ADD_SUBDIRECTORY(sheets_packer_shard)
+      ENDIF()
     ENDIF()
   ENDIF()
 

From 09ea41679fe6f688d099760106fd03e87cdf01c6 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 07:05:26 +0800
Subject: [PATCH 47/75] Fix build project. Can't build server tools without ai
 share

---
 code/ryzom/tools/CMakeLists.txt        | 9 +++++++--
 code/ryzom/tools/client/CMakeLists.txt | 2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/code/ryzom/tools/CMakeLists.txt b/code/ryzom/tools/CMakeLists.txt
index 789ec684f..b97c9be8e 100644
--- a/code/ryzom/tools/CMakeLists.txt
+++ b/code/ryzom/tools/CMakeLists.txt
@@ -1,3 +1,6 @@
+
+FIND_PACKAGE(MySQL)
+
 IF(WITH_RYZOM_TOOLS)
   ADD_SUBDIRECTORY(skill_extractor)
   ADD_SUBDIRECTORY(make_alias_file)
@@ -17,7 +20,6 @@ IF(WITH_RYZOM_TOOLS)
     ADD_SUBDIRECTORY(patch_gen)
 
     IF(WIN32)
-      FIND_PACKAGE(MySQL)
       IF(MYSQL_FOUND)
         ADD_SUBDIRECTORY(sheets_packer_shard)
       ENDIF()
@@ -30,7 +32,10 @@ IF(WITH_RYZOM_TOOLS)
 ENDIF()
 
 ADD_SUBDIRECTORY(client)
-ADD_SUBDIRECTORY(server)
+
+IF(MYSQL_FOUND)
+  ADD_SUBDIRECTORY(server)
+ENDIF()
 
 # Old stuff that doesn't compile anymore.
 #ADD_SUBDIRECTORY(occ2huff)
diff --git a/code/ryzom/tools/client/CMakeLists.txt b/code/ryzom/tools/client/CMakeLists.txt
index 66f8c9b48..d4f136b3c 100644
--- a/code/ryzom/tools/client/CMakeLists.txt
+++ b/code/ryzom/tools/client/CMakeLists.txt
@@ -14,6 +14,6 @@ IF(WITH_QT5 AND WITH_RYZOM_INSTALLER)
   ADD_SUBDIRECTORY(ryzom_installer)
 ENDIF()
 
-IF(WITH_RYZOM_TOOLS)
+IF(WITH_RYZOM_TOOLS AND MYSQL_FOUND)
   ADD_SUBDIRECTORY(r2_islands_textures)
 ENDIF()

From 14304c7f643577337e5a04eaf2210d21e3681199 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 07:05:48 +0800
Subject: [PATCH 48/75] Cleaning up unicode conversion

---
 .../mission_compiler_fe.cpp                   |  2 +-
 .../mission_compiler_feDlg.cpp                | 70 +++++++++----------
 2 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_fe.cpp b/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_fe.cpp
index 9cea31379..73ee44428 100644
--- a/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_fe.cpp
+++ b/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_fe.cpp
@@ -79,7 +79,7 @@ BOOL CMissionCompilerFeApp::InitInstance()
 #endif
 
 	// look at the command line parameters for command line mode
-	string cmdLine = m_lpCmdLine;
+	string cmdLine = NLMISC::tStrToUtf8(m_lpCmdLine);
 	if (cmdLine.find("-c") != string::npos)
 	{
 		NLMISC::createDebug();
diff --git a/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_feDlg.cpp b/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_feDlg.cpp
index fdbf9e668..350203ae7 100644
--- a/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_feDlg.cpp
+++ b/code/ryzom/tools/leveldesign/mission_compiler_fe/mission_compiler_feDlg.cpp
@@ -184,7 +184,7 @@ BOOL CMissionCompilerFeDlg::OnInitDialog()
 	if (SearchPaths.size() > 1)
 	{
 		CWnd* pWnd = GetDlgItem(IDC_PATH_WARNING);
-		pWnd->SetWindowText("Warning ! config file contains more than one path ! Only the first is shown ! ");
+		pWnd->SetWindowText(_T("Warning ! config file contains more than one path ! Only the first is shown ! "));
 	}
 
 	UpdateData(FALSE);
@@ -196,16 +196,16 @@ BOOL CMissionCompilerFeDlg::OnInitDialog()
 	// Check if the file "tmptool.txt" exists in system temp directory
 	// It's that way world_editor pass arguments to the program
 	// The file contains a list of primitives to select
-	char tmpPath[MAX_PATH];
-	GetEnvironmentVariable("TMP", tmpPath, MAX_PATH);
-	strcat(tmpPath, "\\tmptool.txt");
+	TCHAR tmpPath[MAX_PATH];
+	GetEnvironmentVariable(_T ("TMP"), tmpPath, MAX_PATH);
+	_tcscat(tmpPath, _T("\\tmptool.txt"));
 
-	if (NLMISC::CFile::fileExists(tmpPath))
+	if (NLMISC::CFile::fileExists(NLMISC::tStrToUtf8(tmpPath)))
 	{
-		FILE *f = nlfopen(tmpPath, "r");
+		FILE *f = _tfopen(tmpPath, _T("r"));
 		if (f == NULL)
 		{
-			nlinfo("Can't open the file for reading !\n%s", tmpPath);
+			nlinfo("Can't open the file for reading !\n%s", nlTStrToUtf8(tmpPath));
 			return TRUE;
 		}
 
@@ -222,7 +222,7 @@ BOOL CMissionCompilerFeDlg::OnInitDialog()
 		fclose(f);
 
 		// delete temp file
-		NLMISC::CFile::deleteFile(tmpPath);
+		NLMISC::CFile::deleteFile(NLMISC::tStrToUtf8(tmpPath));
 
 		// Test to check if the primitive is in src list
 		// If it is, erase it form src and add it to dest
@@ -240,8 +240,8 @@ BOOL CMissionCompilerFeDlg::OnInitDialog()
 				files[i] = toUpper(CPath::standardizeDosPath(files[i]));
 				if (srcPath != files[i])
 				{
-					::MessageBox(NULL, "Primitive path and working directory are not the same !",
-									   "Mission compiler", MB_OK|MB_ICONEXCLAMATION);
+					::MessageBox(NULL, _T("Primitive path and working directory are not the same !"),
+									   _T("Mission compiler"), MB_OK|MB_ICONEXCLAMATION);
 				}
 				else
 				{
@@ -252,8 +252,8 @@ BOOL CMissionCompilerFeDlg::OnInitDialog()
 			else
 			{
 				char buffer[1024];
-				sprintf(buffer, "Can't find primitive in the directory !\n%s\n", files[i].c_str(), m_dataDirectory);
-				::MessageBox(NULL, buffer, "Mission compiler", MB_OK|MB_ICONEXCLAMATION);
+				sprintf(buffer, "Can't find primitive in the directory !\n%s\n", files[i].c_str(), nlTStrToUtf8(m_dataDirectory));
+				::MessageBox(NULL, nlUtf8ToTStr(buffer), _T("Mission compiler"), MB_OK|MB_ICONEXCLAMATION);
 			}
 		}
 
@@ -274,7 +274,7 @@ void CMissionCompilerFeDlg::fillSourceList()
 	addPath.CenterWindow();
 	addPath.ShowWindow(SW_SHOW);
 
-	string log(addPath.m_addPathLog);
+	string log = tStrToUtf8(addPath.m_addPathLog);
 	log += "Reading config file\r\n";
 	addPath.m_addPathLog = log.c_str();
 	addPath.UpdateData(FALSE);
@@ -283,7 +283,7 @@ void CMissionCompilerFeDlg::fillSourceList()
 	// Fill the src list with available primitives
 	for (uint i=0; i<SearchPaths.size(); ++i)
 	{
-		log = addPath.m_addPathLog;
+		log = tStrToUtf8(addPath.m_addPathLog);
 		log += SearchPaths[i]+"\r\n";
 		addPath.m_addPathLog = log.c_str();
 		addPath.UpdateData(FALSE);
@@ -319,7 +319,7 @@ bool CMissionCompilerFeDlg::readConfigFile()
 	}
 	else
 	{
-		AfxMessageBox("Can't find configuration var 'SearchPath', fatal", MB_OK);
+		AfxMessageBox(_T("Can't find configuration var 'SearchPath', fatal"), MB_OK);
 		PostQuitMessage(-1);
 		return false;
 	}
@@ -329,7 +329,7 @@ bool CMissionCompilerFeDlg::readConfigFile()
 		LigoConfigFile = var->asString();
 	else
 	{
-		AfxMessageBox("Can't find configuration var 'ligo_config', fatal", MB_OK);
+		AfxMessageBox(_T("Can't find configuration var 'ligo_config', fatal"), MB_OK);
 		PostQuitMessage(-1);
 		return false;
 	}
@@ -383,7 +383,7 @@ bool CMissionCompilerFeDlg::readConfigFile()
 		{
 			CWnd* pWnd = GetDlgItem(IDC_CHECK_SRV1 + i);
 			pWnd->EnableWindow(TRUE);
-			pWnd->SetWindowText(names->asString(i).c_str());
+			pWnd->SetWindowText(nlUtf8ToTStr(names->asString(i)));
 
 			ServerName.push_back(names->asString(i));
 			ServerPathPrim.push_back(pathsPrim->asString(i));
@@ -412,15 +412,15 @@ void CMissionCompilerFeDlg::updateFileList()
 		for (uint i=0; first != last; ++first)
 		{
 			if (m_filter.GetLength() == 0)
-				m_listSrc.InsertString(i++, first->first.c_str());
+				m_listSrc.InsertString(i++, nlUtf8ToTStr(first->first));
 			else
 			{
 				// check the filter
-				string filter(m_filter.LockBuffer());
+				string filter = tStrToUtf8(m_filter.LockBuffer());
 				m_filter.UnlockBuffer();
 
 				if (first->first.find(filter) != string::npos)
-					m_listSrc.InsertString(i++, first->first.c_str());
+					m_listSrc.InsertString(i++, nlUtf8ToTStr(first->first));
 			}
 		}
 	}
@@ -429,7 +429,7 @@ void CMissionCompilerFeDlg::updateFileList()
 		TFileList::iterator first(_DstList.begin()), last(_DstList.end());
 		for (uint i=0; first != last; ++first,++i)
 		{
-			m_listDst.InsertString(i, first->first.c_str());
+			m_listDst.InsertString(i, nlUtf8ToTStr(first->first));
 		}
 	}
 }
@@ -493,7 +493,7 @@ void CMissionCompilerFeDlg::compile(BOOL publish)
 			dlg.UpdateData(FALSE);
 //			dlg.m_compileLogCtrl.SetSel(compileLog.size(), compileLog.size(), FALSE);
 			dlg.RedrawWindow();
-			AfxMessageBox(msg.c_str());
+			AfxMessageBox(nlUtf8ToTStr(msg));
 			break;
 		}
 	}
@@ -569,7 +569,7 @@ void CMissionCompilerFeDlg::OnAdd()
 	{
 		CString tmp;
 		m_listSrc.GetText(sel[i], tmp);
-		string file(tmp.LockBuffer());
+		string file = tStrToUtf8(tmp.LockBuffer());
 		tmp.UnlockBuffer();
 		_DstList.insert(make_pair(file, _SrcList[file]));
 		_SrcList.erase(file);
@@ -585,7 +585,7 @@ void CMissionCompilerFeDlg::OnAddAll()
 	{
 		CString tmp;
 		m_listSrc.GetText(0, tmp);
-		string file(tmp.LockBuffer());
+		string file = tStrToUtf8(tmp.LockBuffer());
 		tmp.UnlockBuffer();
 
 		_DstList.insert(make_pair(file, _SrcList[file]));
@@ -608,7 +608,7 @@ void CMissionCompilerFeDlg::OnRemove()
 	{
 		CString tmp;
 		m_listDst.GetText(sel[i], tmp);
-		string file(tmp.LockBuffer());
+		string file = tStrToUtf8(tmp.LockBuffer());
 		tmp.UnlockBuffer();
 		_SrcList.insert(make_pair(file, _DstList[file]));
 		_DstList.erase(file);
@@ -662,7 +662,7 @@ void CMissionCompilerFeDlg::OnSpecialRuncompilertest()
 		CMissionCompiler mc;
 		if (!mc.compileMissions(primDoc.RootNode, sourceDocName))
 		{
-			AfxMessageBox("Error while compiling the test primitive, correct error(s) first");
+			AfxMessageBox(_T("Error while compiling the test primitive, correct error(s) first"));
 			return;
 		}
 		TMissionDataPtr testMission = mc.getMission(0);
@@ -699,7 +699,7 @@ void CMissionCompilerFeDlg::OnSpecialRuncompilertest()
 	{
 		string msg = "In primitive ";
 		msg += buildPrimPath(e.Primitive) + ": " + e.Why;
-		AfxMessageBox(utf8ToTStr(msg));
+		AfxMessageBox(nlUtf8ToTStr(msg));
 	}
 	
 }
@@ -991,21 +991,21 @@ void CMissionCompilerFeDlg::OnChangeDir()
 
 	// open a dialog to choose a directory
 	BROWSEINFO	bi;
-	char		str[MAX_PATH];
-	ITEMIDLIST*	pidl;
-	char sTemp[1024];
+	TCHAR		str[MAX_PATH];
+	LPITEMIDLIST pidl;
+	TCHAR sTemp[1024];
 
 	// fill the structure with options
 	bi.hwndOwner = this->m_hWnd;
 	bi.pidlRoot = NULL;
 	bi.pidlRoot = NULL;
 	bi.pszDisplayName = sTemp;
-	bi.lpszTitle = "Choose the data directory";
+	bi.lpszTitle = _T("Choose the data directory");
 	bi.ulFlags = 0;
 	bi.lpfn = dataDirBrowseCallbackProc;
 
-	char sDir[512];
-	strcpy(sDir, m_dataDirectory);
+	TCHAR sDir[512];
+	_tcscpy(sDir, m_dataDirectory);
 	bi.lParam = (LPARAM)sDir;
 	bi.iImage = 0;
 	pidl = SHBrowseForFolder (&bi);
@@ -1013,7 +1013,7 @@ void CMissionCompilerFeDlg::OnChangeDir()
 	if (SHGetPathFromIDList(pidl, str)) 
 	{
 		m_dataDirectory = str;
-		SearchPaths[0] = str;
+		SearchPaths[0] = tStrToUtf8(str);
 		fillSourceList();
 		updateFileList();
 		UpdateData(FALSE);
@@ -1023,7 +1023,7 @@ void CMissionCompilerFeDlg::OnChangeDir()
 void CMissionCompilerFeDlg::OnChangeDataDir() 
 {
 	UpdateData(TRUE);
-	SearchPaths[0] = m_dataDirectory;
+	SearchPaths[0] = tStrToUtf8(m_dataDirectory);
 	fillSourceList();
 	updateFileList();
 	UpdateData(FALSE);

From 44b7adb5698779be432999f755e2a8084112023f Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 07:35:00 +0800
Subject: [PATCH 49/75] Cleaning up unicode conversion and fixing 64bit issues

---
 code/nel/include/nel/net/service.h            |  8 +-
 code/nel/tools/3d/cluster_viewer/view_cs.cpp  |  4 +-
 code/nel/tools/3d/shapes_exporter/main.cpp    |  2 +-
 code/nel/tools/3d/zviewer/zviewer.cpp         |  9 +-
 .../logic/logic_editor_dll/Condition.cpp      |  8 +-
 .../tools/logic/logic_editor_dll/Counter.cpp  |  2 +-
 .../tools/logic/logic_editor_dll/State.cpp    | 10 +-
 .../logic_editor_exe/logic_editor_exe.cpp     |  5 +-
 .../tools/misc/message_box/message_box.cpp    |  6 +-
 .../multi_cd_setup_fix/multi_cd_setup_fix.cpp |  6 +-
 .../leveldesign/georges_dll/base_dialog.cpp   |  2 +-
 .../leveldesign/georges_dll/dfn_dialog.cpp    | 22 ++---
 .../leveldesign/georges_dll/dfn_dialog.h      |  4 +-
 .../georges_dll/edit_list_ctrl.cpp            | 22 ++---
 .../georges_dll/file_browser_dialog.cpp       |  6 +-
 .../georges_dll/file_tree_view.cpp            | 22 ++---
 .../leveldesign/georges_dll/file_tree_view.h  |  2 +-
 .../leveldesign/georges_dll/form_dialog.cpp   | 44 ++++-----
 .../georges_dll/georges_edit_doc.cpp          |  8 +-
 .../georges_dll/georges_edit_view.cpp         |  2 +-
 .../georges_dll/georges_implementation.cpp    |  4 +-
 .../leveldesign/georges_dll/header_dialog.cpp |  2 +-
 .../leveldesign/georges_dll/imagelist_ex.cpp  |  2 +-
 .../leveldesign/georges_dll/left_view.cpp     |  6 +-
 .../leveldesign/georges_dll/main_frm.cpp      |  8 +-
 .../georges_dll/memory_combo_box.h            |  2 +-
 .../georges_dll/output_console_dlg.cpp        |  2 +-
 .../georges_dll/settings_dialog.cpp           | 28 +++---
 .../leveldesign/georges_dll/type_dialog.cpp   | 96 +++++++++----------
 .../leveldesign/georges_exe/georges_exe.cpp   |  8 +-
 .../georges_plugin_sound/PageBgFades.cpp      | 16 ++--
 .../georges_plugin_sound/PageBgFlags.cpp      |  4 +-
 .../georges_plugin_sound/PageComtext.cpp      |  4 +-
 .../georges_plugin_sound.cpp                  |  5 +-
 .../georges_plugin_sound/listener_view.cpp    |  6 +-
 .../georges_plugin_sound/sound_dialog.cpp     | 10 +-
 .../georges_plugin_sound/sound_plugin.cpp     | 13 ++-
 37 files changed, 196 insertions(+), 214 deletions(-)

diff --git a/code/nel/include/nel/net/service.h b/code/nel/include/nel/net/service.h
index 02967d317..bdabb48a1 100644
--- a/code/nel/include/nel/net/service.h
+++ b/code/nel/include/nel/net/service.h
@@ -117,11 +117,11 @@ class IServiceUpdatable;
 #if defined(NL_OS_WINDOWS) && defined(_WINDOWS)
 #define NLNET_SERVICE_MAIN(__ServiceClassName, __ServiceShortName, __ServiceLongName, __ServicePort, __ServiceCallbackArray, __ConfigDir, __LogDir) \
  \
-int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) \
+int APIENTRY nltWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) \
 { \
 	NLMISC::CApplicationContext	serviceContext; \
 	__ServiceClassName *scn = new __ServiceClassName; \
-	scn->setArgs (lpCmdLine); \
+	scn->setArgs (nlTStrToUtf8(lpCmdLine)); \
 	createDebug(NULL,!scn->haveLongArg("nolog"));\
 	scn->setCallbackArray (__ServiceCallbackArray, sizeof(__ServiceCallbackArray)/sizeof(__ServiceCallbackArray[0])); \
     sint retval = scn->main (__ServiceShortName, __ServiceLongName, __ServicePort, __ConfigDir, __LogDir, __DATE__ " " __TIME__); \
@@ -132,11 +132,11 @@ int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
 #else
 #define NLNET_SERVICE_MAIN(__ServiceClassName, __ServiceShortName, __ServiceLongName, __ServicePort, __ServiceCallbackArray, __ConfigDir, __LogDir) \
  \
-int main(int argc, const char **argv) \
+int nltmain(int argc, const NLMISC::tchar **argv) \
 { \
 	NLMISC::CApplicationContext serviceContext; \
 	__ServiceClassName *scn = new __ServiceClassName; \
-	scn->setArgs (argc, argv); \
+	scn->setArgs (argc, nlTStrToUtf8(argv)); \
 	createDebug(NULL,!scn->haveLongArg("nolog"));\
 	scn->setCallbackArray (__ServiceCallbackArray, sizeof(__ServiceCallbackArray)/sizeof(__ServiceCallbackArray[0])); \
 	sint retval = scn->main (__ServiceShortName, __ServiceLongName, __ServicePort, __ConfigDir, __LogDir, __DATE__ " " __TIME__); \
diff --git a/code/nel/tools/3d/cluster_viewer/view_cs.cpp b/code/nel/tools/3d/cluster_viewer/view_cs.cpp
index fa5485ca0..b08cab749 100644
--- a/code/nel/tools/3d/cluster_viewer/view_cs.cpp
+++ b/code/nel/tools/3d/cluster_viewer/view_cs.cpp
@@ -201,9 +201,9 @@ void LoadSceneScript (const char *ScriptName, CScene* pScene, vector<SDispCS> &D
 // Main
 // ---------------------------------------------------------------------------
 #ifdef NL_OS_WINDOWS
-int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
+int APIENTRY nltWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
 #else // NL_OS_WINDOWS
-int main(int argc, char **argv)
+int nltmain(int argc, NLMISC::tchar **argv)
 #endif // NL_OS_WINDOWS
 {
 	double rGlobalTime = 0;
diff --git a/code/nel/tools/3d/shapes_exporter/main.cpp b/code/nel/tools/3d/shapes_exporter/main.cpp
index a77161849..8c42f740c 100644
--- a/code/nel/tools/3d/shapes_exporter/main.cpp
+++ b/code/nel/tools/3d/shapes_exporter/main.cpp
@@ -88,7 +88,7 @@ static CHashKeyMD5 getNewMD5(const std::string &filename)
 }
 
 #if defined(NL_OS_WINDOWS) && !defined(_CONSOLE)
-sint WINAPI WinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPSTR cmdline, int /* nCmdShow */)
+sint APIENTRY WinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPSTR cmdline, int /* nCmdShow */)
 {
 	// we can specify several shapes on command line
 	// so we need to process it
diff --git a/code/nel/tools/3d/zviewer/zviewer.cpp b/code/nel/tools/3d/zviewer/zviewer.cpp
index fc8e00a4c..3af4df8d2 100644
--- a/code/nel/tools/3d/zviewer/zviewer.cpp
+++ b/code/nel/tools/3d/zviewer/zviewer.cpp
@@ -953,12 +953,11 @@ void initViewerConfig(const char * configFileName)
 							MAIN
 \****************************************************************/
 #ifdef NL_OS_WINDOWS
-int WINAPI WinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPSTR cmdline, int /* nCmdShow */)
+int APIENTRY nltWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR /* lpCmdLine */, int /* nCmdShow */)
+#else // NL_OS_WINDOWS
+int nltmain(int /* argc */, NLMISC::tchar ** /* argv */)
+#endif // NL_OS_WINDOWS
 {
-#else
-int main(int /* argc */, char ** /* argv */)
-{
-#endif
 	try
 	{
 		NLMISC::CApplicationContext myApplicationContext;
diff --git a/code/nel/tools/logic/logic_editor_dll/Condition.cpp b/code/nel/tools/logic/logic_editor_dll/Condition.cpp
index ba248a80d..8caa9d967 100644
--- a/code/nel/tools/logic/logic_editor_dll/Condition.cpp
+++ b/code/nel/tools/logic/logic_editor_dll/Condition.cpp
@@ -260,8 +260,8 @@ void cConditionNodeToCLogicConditionNode(CConditionNode * conditionNode, CLogicC
 			{
 				logicConditionNode->LogicBlock.Type = CLogicConditionLogicBlock::COMPARISON;
 				
-				logicConditionNode->LogicBlock.ComparisonBlock.VariableName = tStrToUtf8(conditionNode->m_sVariableName);
-				logicConditionNode->LogicBlock.ComparisonBlock.Operator = tStrToUtf8(conditionNode->m_sOperator);
+				logicConditionNode->LogicBlock.ComparisonBlock.VariableName = NLMISC::tStrToUtf8(conditionNode->m_sVariableName);
+			    logicConditionNode->LogicBlock.ComparisonBlock.Operator = NLMISC::tStrToUtf8(conditionNode->m_sOperator);
 				logicConditionNode->LogicBlock.ComparisonBlock.Comparand = (sint64)conditionNode->m_dComparand;
 			}
 			break;
@@ -270,7 +270,7 @@ void cConditionNodeToCLogicConditionNode(CConditionNode * conditionNode, CLogicC
 			{
 				logicConditionNode->LogicBlock.Type = CLogicConditionLogicBlock::SUB_CONDITION;
 				
-				logicConditionNode->LogicBlock.SubCondition = tStrToUtf8(conditionNode->m_sConditionName);
+				logicConditionNode->LogicBlock.SubCondition = NLMISC::tStrToUtf8(conditionNode->m_sConditionName);
 			}
 			break;
 		}
@@ -298,7 +298,7 @@ void cConditionNodeToCLogicConditionNode(CConditionNode * conditionNode, CLogicC
 void cConditionToCLogicCondition( CCondition& condition, CLogicCondition& logicCondition )
 {
 	// condition name
-	logicCondition.setName(tStrToUtf8(condition.m_sName));
+	logicCondition.setName(NLMISC::tStrToUtf8(condition.m_sName));
 
 	// nodes
 	POSITION pos;
diff --git a/code/nel/tools/logic/logic_editor_dll/Counter.cpp b/code/nel/tools/logic/logic_editor_dll/Counter.cpp
index 52537ea08..3a6afc9a3 100644
--- a/code/nel/tools/logic/logic_editor_dll/Counter.cpp
+++ b/code/nel/tools/logic/logic_editor_dll/Counter.cpp
@@ -45,7 +45,7 @@ CCounter::~CCounter()
 void cCounterToCLogicCounter( CCounter& counter, CLogicCounter& logicCounter )
 {
 	// counter name
-	logicCounter.setName(tStrToUtf8(counter.m_sName));
+	logicCounter.setName(NLMISC::tStrToUtf8(counter.m_sName));
 	
 	// running mode
 	if( counter.m_sMode == "Shuttle" )
diff --git a/code/nel/tools/logic/logic_editor_dll/State.cpp b/code/nel/tools/logic/logic_editor_dll/State.cpp
index fbfdebb2d..306128c1f 100644
--- a/code/nel/tools/logic/logic_editor_dll/State.cpp
+++ b/code/nel/tools/logic/logic_editor_dll/State.cpp
@@ -70,7 +70,7 @@ bool operator==( const CEvent &ev1, const CEvent &ev2)
 void cEventToCLogicEvent( CEvent& event, CLogicEvent& logicEvent )
 {
 	/// condition name
-	logicEvent.ConditionName = tStrToUtf8(event.m_sConditionName);
+	logicEvent.ConditionName = NLMISC::tStrToUtf8(event.m_sConditionName);
 	
 	/// event action
 	logicEvent.EventAction.IsStateChange = !event.m_bActionIsMessage;
@@ -78,18 +78,18 @@ void cEventToCLogicEvent( CEvent& event, CLogicEvent& logicEvent )
 	if( logicEvent.EventAction.IsStateChange )
 	{
 		/// state name for state change
-		logicEvent.EventAction.StateChange = tStrToUtf8(event.m_sStateChange);
+		logicEvent.EventAction.StateChange = NLMISC::tStrToUtf8(event.m_sStateChange);
 	}
 	else
 	{
 		/// message destination
-		logicEvent.EventAction.EventMessage.Destination = tStrToUtf8(event.m_sMessageDestination);
+		logicEvent.EventAction.EventMessage.Destination = NLMISC::tStrToUtf8(event.m_sMessageDestination);
 		
 		/// message id
 		logicEvent.EventAction.EventMessage.MessageId = "LOGIC"; //string( (LPCSTR)event.m_sMessageID ); //TEMP!!!
 
 		/// message arguments
-		logicEvent.EventAction.EventMessage.Arguments = tStrToUtf8(event.m_sArguments);
+		logicEvent.EventAction.EventMessage.Arguments = NLMISC::tStrToUtf8(event.m_sArguments);
 	}
 
 } // cEventToCLogicEvent //
@@ -176,7 +176,7 @@ BOOL CState::removeEvent( CEvent *event)
 void cStateToCLogicState( CState& state, CLogicState& logicState )
 {
 	/// state name
-	logicState.setName(tStrToUtf8(state.m_sName));
+	logicState.setName(NLMISC::tStrToUtf8(state.m_sName));
 
 	POSITION pos;
 	for( pos = state.m_evEvents.GetHeadPosition(); pos != NULL; )
diff --git a/code/nel/tools/logic/logic_editor_exe/logic_editor_exe.cpp b/code/nel/tools/logic/logic_editor_exe/logic_editor_exe.cpp
index 4871eae79..912f4fc26 100644
--- a/code/nel/tools/logic/logic_editor_exe/logic_editor_exe.cpp
+++ b/code/nel/tools/logic/logic_editor_exe/logic_editor_exe.cpp
@@ -28,10 +28,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
-int APIENTRY WinMain(HINSTANCE hInstance,
-                     HINSTANCE hPrevInstance,
-                     LPSTR     lpCmdLine,
-                     int       nCmdShow)
+int APIENTRY _tWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR /* lpCmdLine */, int /* nCmdShow */)
 {
  	// Create a logic editor
 	ILogicEditor * logicEditor = ILogicEditor::getInterface();
diff --git a/code/nel/tools/misc/message_box/message_box.cpp b/code/nel/tools/misc/message_box/message_box.cpp
index dd2ced825..ae8866a16 100644
--- a/code/nel/tools/misc/message_box/message_box.cpp
+++ b/code/nel/tools/misc/message_box/message_box.cpp
@@ -19,11 +19,7 @@
 #include <stdio.h>
 
 using namespace std;
-
-int APIENTRY WinMain(HINSTANCE hInstance,
-                     HINSTANCE hPrevInstance,
-                     LPSTR     lpCmdLine,
-                     int       nCmdShow)
+int APIENTRY _tWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR /* lpCmdLine */, int /* nCmdShow */)
 {
 	char *filename;
 	if (filename = strstr (lpCmdLine, "-f "))
diff --git a/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp b/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
index 9e20c09a0..9d9e9b590 100644
--- a/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
+++ b/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
@@ -40,11 +40,7 @@ void pump ()
 		DispatchMessage(&msg);
 	}
 }
-
-int APIENTRY _tWinMain(HINSTANCE hInstance,
-                     HINSTANCE hPrevInstance,
-                     LPSTR     lpCmdLine,
-                     int       nCmdShow)
+int APIENTRY _tWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR /* lpCmdLine */, int /* nCmdShow */)
 {
 	// Windows
 	HWND hwnd = CreateDialog (hInstance, MAKEINTRESOURCE(IDD_WAIT), NULL, MyDialogProc);
diff --git a/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp
index ffacde032..923d69c6b 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/base_dialog.cpp
@@ -232,7 +232,7 @@ BOOL CBaseDialog::PreTranslateMessage(MSG* pMsg)
 
 void CBaseDialog::setEditTextMultiLine (CEdit &edit, const char *text)
 {
-	edit.SetWindowText (utf8ToTStr(NLMISC::addSlashR(text)));
+	edit.SetWindowText (nlUtf8ToTStr(NLMISC::addSlashR(text)));
 }	
 
 void CBaseDialog::onOpenSelected() 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
index 72a446870..3958901a2 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.cpp
@@ -193,7 +193,7 @@ void CDfnDialog::getFromDocument (const NLGEORGES::CFormDfn &dfn)
 		for (parent=0; parent<dfn.getNumParent (); parent++)
 		{
 			// Add the label and value
-			Parents.ListCtrl.InsertItem (parent, utf8ToTStr(dfn.getParentFilename (parent)));
+			Parents.ListCtrl.InsertItem(parent, nlUtf8ToTStr(dfn.getParentFilename(parent)));
 		}
 
 		// Add the struct element
@@ -202,12 +202,12 @@ void CDfnDialog::getFromDocument (const NLGEORGES::CFormDfn &dfn)
 		for (elm=0; elm<dfn.getNumEntry (); elm++)
 		{
 			// Add the label and value
-			Struct.ListCtrl.InsertItem (elm, utf8ToTStr(dfn.getEntry (elm).getName()));
+			Struct.ListCtrl.InsertItem(elm, nlUtf8ToTStr(dfn.getEntry(elm).getName()));
 			switch (elm, dfn.getEntry (elm).getType ())
 			{
 			case UFormDfn::EntryType:
 				Struct.ListCtrl.SetItemText (elm, 1, dfn.getEntry (elm).getArrayFlag () ? _T("Type array") : _T("Type"));
-				Struct.ListCtrl.SetItemText (elm, 4, utf8ToTStr(dfn.getEntry (elm).getFilenameExt ()));
+				Struct.ListCtrl.SetItemText(elm, 4, nlUtf8ToTStr(dfn.getEntry(elm).getFilenameExt()));
 				break;
 			case UFormDfn::EntryDfn:
 				Struct.ListCtrl.SetItemText (elm, 1, dfn.getEntry (elm).getArrayFlag () ? _T("Dfn array") : _T("Dfn"));
@@ -216,8 +216,8 @@ void CDfnDialog::getFromDocument (const NLGEORGES::CFormDfn &dfn)
 				Struct.ListCtrl.SetItemText (elm, 1, _T("Virtual Dfn"));
 				break;
 			}
-			Struct.ListCtrl.SetItemText (elm, 2, utf8ToTStr(dfn.getEntry (elm).getFilename()));
-			Struct.ListCtrl.SetItemText (elm, 3, utf8ToTStr(dfn.getEntry (elm).getDefault()));
+			Struct.ListCtrl.SetItemText(elm, 2, nlUtf8ToTStr(dfn.getEntry(elm).getFilename()));
+			Struct.ListCtrl.SetItemText(elm, 3, nlUtf8ToTStr(dfn.getEntry(elm).getDefault()));
 		}
 	}
 }
@@ -385,7 +385,7 @@ void CDfnEditListCtrl::getNewItemText (uint item, uint subItem, std::string &ret
 
 // ***************************************************************************
 
-void CDfnEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter)
+void CDfnEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, NLMISC::tstring &filter)
 {
 	if (subItem == 2)
 	{
@@ -422,7 +422,7 @@ void CDfnEditListCtrl::onItemChanged (uint item, uint subItem)
 			str = Dialog->Struct.ListCtrl.GetItemText (item, 2);
 			std::string ext = NLMISC::CFile::getExtension(tStrToUtf8(str));
 			if (ext == "typ")
-				Dialog->Struct.ListCtrl.SetItemText (item, 2, utf8ToTStr(theApp.DefaultType));
+				Dialog->Struct.ListCtrl.SetItemText(item, 2, nlUtf8ToTStr(theApp.DefaultType));
 		}
 		else if ((type == "Dfn") || (type == "Dfn array"))
 		{
@@ -430,7 +430,7 @@ void CDfnEditListCtrl::onItemChanged (uint item, uint subItem)
 			str = Dialog->Struct.ListCtrl.GetItemText (item, 2);
 			std::string ext = NLMISC::CFile::getExtension(tStrToUtf8(str));
 			if (ext == "dfn")
-				Dialog->Struct.ListCtrl.SetItemText (item, 2, utf8ToTStr(theApp.DefaultDfn));
+				Dialog->Struct.ListCtrl.SetItemText(item, 2, nlUtf8ToTStr(theApp.DefaultDfn));
 
 			// Clear default value
 			Dialog->Struct.ListCtrl.SetItemText (item, 3, _T(""));
@@ -472,7 +472,7 @@ void CDfnDialog::onOpenSelected ()
 					if (str != "")
 					{
 						// Look for the file
-						CString name = utf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
+						CString name = nlUtf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
 						if (name.IsEmpty())
 							name = str;
 
@@ -494,7 +494,7 @@ void CDfnDialog::onOpenSelected ()
 					if (str != "")
 					{
 						// Look for the file
-						CString name = utf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
+						CString name = nlUtf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
 						if (name.IsEmpty())
 							name = str;
 
@@ -621,7 +621,7 @@ void CDfnParentEditListCtrl::getNewItemText (uint item, uint subItem, std::strin
 
 // ***************************************************************************
 
-void CDfnParentEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter)
+void CDfnParentEditListCtrl::getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, NLMISC::tstring &filter)
 {
 	filter = DfnFilter;
 	defDir = theApp.RootSearchPath;
diff --git a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h
index 785d64539..4d7479ea6 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/dfn_dialog.h
@@ -36,7 +36,7 @@ class CDfnParentEditListCtrl : public CEditListCtrl
 	CEditListCtrl::TItemEdit	getItemEditMode (uint item, uint subItem);
 	void						getMemComboBoxProp (uint item, uint subItem, std::string &regAdr, bool &browse);
 	void						getNewItemText (uint item, uint subItem, std::string &ret);
-	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter);
+	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, NLMISC::tstring &filter);
 public:
 	class CDfnDialog			*Dialog;
 };
@@ -47,7 +47,7 @@ class CDfnEditListCtrl : public CEditListCtrl
 	void						getComboBoxStrings (uint item, uint subItem, std::vector<std::string> &retStrings);
 	void						getMemComboBoxProp (uint item, uint subItem, std::string &regAdr, bool &browse);
 	void						getNewItemText (uint item, uint subItem, std::string &ret);
-	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, std::tstring &filter);
+	void						getBrowseInfo (uint item, uint subItem, std::string &defExt, std::string &defFilename, std::string &defDir, NLMISC::tstring &filter);
 	void						onItemChanged (uint item, uint subItem);
 public:
 	class CDfnDialog			*Dialog;
diff --git a/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp b/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp
index bad4b8a1e..3e4d02046 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/edit_list_ctrl.cpp
@@ -122,11 +122,11 @@ BOOL CEditListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
 				// Insert an item at the end
 				string text;
 				getNewItemText (ListCtrl.GetItemCount (), 0, text);
-				ListCtrl.InsertItem (ListCtrl.GetItemCount (), utf8ToTStr(text));
+			    ListCtrl.InsertItem(ListCtrl.GetItemCount(), nlUtf8ToTStr(text));
 				for (uint i=1; i<ColumnCount; i++)
 				{
 					getNewItemText (ListCtrl.GetItemCount ()-1, i, text);
-					ListCtrl.SetItemText (ListCtrl.GetItemCount ()-1, i, utf8ToTStr(text));
+				    ListCtrl.SetItemText(ListCtrl.GetItemCount() - 1, i, nlUtf8ToTStr(text));
 				}
 				ListCtrl.SetItemState (ListCtrl.GetItemCount ()-1, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
 
@@ -151,22 +151,22 @@ BOOL CEditListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
 						item = ListCtrl.GetNextSelectedItem(pos);
 						string text;
 						getNewItemText (item, 0, text);
-						ListCtrl.InsertItem (item, utf8ToTStr(text));
+				        ListCtrl.InsertItem(item, nlUtf8ToTStr(text));
 						for (uint i=1; i<ColumnCount; i++)
 						{
 							getNewItemText (item, i, text);
-							ListCtrl.SetItemText (item, i, utf8ToTStr(text));
+					        ListCtrl.SetItemText(item, i, nlUtf8ToTStr(text));
 						}
 					}
 					else
 					{
 						string text;
 						getNewItemText (0, 0, text);
-						ListCtrl.InsertItem (0, utf8ToTStr(text));
+				        ListCtrl.InsertItem(0, nlUtf8ToTStr(text));
 						for (uint i=1; i<ColumnCount; i++)
 						{
 							getNewItemText (0, i, text);
-							ListCtrl.SetItemText (0, i, utf8ToTStr(text));
+					        ListCtrl.SetItemText(0, i, nlUtf8ToTStr(text));
 						}
 						ListCtrl.SetItemState (0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
 					}
@@ -312,9 +312,9 @@ LRESULT CMyListCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
 				Ctrl->getBrowseInfo (Ctrl->Item, Ctrl->SubItem, defExt, defFilename, defDir, filter);
 
 				TCHAR buffer[MAX_PATH];
-				_tcscpy_s(buffer, MAX_PATH, utf8ToTStr(defDir));
+			    _tcscpy_s(buffer, MAX_PATH, nlUtf8ToTStr(defDir));
 
-				CFileDialog dlgFile (TRUE, utf8ToTStr(defExt), utf8ToTStr(defFilename), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, utf8ToTStr(filter), theApp.m_pMainWnd);
+				CFileDialog dlgFile(TRUE, nlUtf8ToTStr(defExt), nlUtf8ToTStr(defFilename), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, nlUtf8ToTStr(filter), theApp.m_pMainWnd);
 				dlgFile.m_ofn.lpstrInitialDir = buffer;
 				Ctrl->OnBrowse = true;
 				if (dlgFile.DoModal () == IDOK)
@@ -453,8 +453,8 @@ void CEditListCtrl::editItem (uint item, uint subitem)
 		getComboBoxStrings (Item, SubItem, retStrings);
 		for (uint i=0; i<retStrings.size (); i++)
 		{
-			Combo.InsertString (-1, utf8ToTStr(retStrings[i]));
-			if (retStrings[i] == tStrToUtf8(tmp))
+			Combo.InsertString(-1, nlUtf8ToTStr(retStrings[i]));
+			if (retStrings[i] == NLMISC::tStrToUtf8(tmp))
 				Combo.SetCurSel (i);
 		}
 
@@ -475,7 +475,7 @@ void CEditListCtrl::editItem (uint item, uint subitem)
 		string retString;
 		bool browse;
 		getMemComboBoxProp (Item, SubItem, retString, browse);
-		MemCombo.setRegisterAdress (utf8ToTStr(retString));
+		MemCombo.setRegisterAdress(nlUtf8ToTStr(retString));
 		MemCombo.clearCommand ();
 		if (browse)
 			MemCombo.addCommand (GEORGES_EDIT_BROWSE_LABEL, CmdBrowse);
diff --git a/code/ryzom/tools/leveldesign/georges_dll/file_browser_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/file_browser_dialog.cpp
index 98cb78b83..a485e994f 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/file_browser_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/file_browser_dialog.cpp
@@ -279,7 +279,7 @@ void CFileBrowserDialog::openDocument ()
 			string pathName = CPath::lookup (filename.c_str (), false, false);
 			if (pathName.empty ())
 				pathName = filename;
-			theApp.OpenDocumentFile (utf8ToTStr(pathName));
+			theApp.OpenDocumentFile(nlUtf8ToTStr(pathName));
 		}
 	}
 	else if (IsWindow (TreeCtrlType) && TreeCtrlDfn.IsWindowVisible ())
@@ -289,7 +289,7 @@ void CFileBrowserDialog::openDocument ()
 			string pathName = CPath::lookup (filename.c_str (), false, false);
 			if (pathName.empty ())
 				pathName = filename;
-			theApp.OpenDocumentFile (utf8ToTStr(pathName));
+			theApp.OpenDocumentFile(nlUtf8ToTStr(pathName));
 		}
 	}
 	else if (TreeCtrlForm.IsWindowVisible ())
@@ -299,7 +299,7 @@ void CFileBrowserDialog::openDocument ()
 			string pathName = CPath::lookup (filename.c_str (), false, false);
 			if (pathName.empty ())
 				pathName = filename;
-			theApp.OpenDocumentFile (utf8ToTStr(pathName));
+			theApp.OpenDocumentFile(nlUtf8ToTStr(pathName));
 		}
 	}
 }
diff --git a/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.cpp b/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.cpp
index 3a0616fe1..d44e5a155 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.cpp
@@ -77,8 +77,8 @@ struct CTreeItemInfo
 		pParentFolder=NULL;
 		dwFlags=NULL;
 	}
-	ITEMIDLIST*   pidlSelf;
-	ITEMIDLIST*   pidlFullyQual;
+	LPITEMIDLIST  pidlSelf;
+	LPITEMIDLIST  pidlFullyQual;
 	IShellFolder* pParentFolder;
 	DWORD		  dwFlags;
 	std::string	  displayName;
@@ -97,8 +97,8 @@ bool CFileTreeCtrl::setRootDirectory (const char *dir)
 			_TreeCtrl.DeleteAllItems ();
 
 			IShellFolder* pDesktop;
-			ITEMIDLIST*   pidl;
-			ITEMIDLIST*   pidlDir;
+			LPITEMIDLIST  pidl;
+			LPITEMIDLIST  pidlDir;
 			TV_ITEM tvItem={0};
 			TV_INSERTSTRUCT   tvInsert={0};
 
@@ -318,11 +318,11 @@ BOOL CFileTreeCtrl::OnNotify ( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
 	return CWnd::OnNotify ( wParam, lParam, pResult );
 }
 
-inline ITEMIDLIST* Pidl_GetNextItem(LPCITEMIDLIST pidl)
+inline LPITEMIDLIST Pidl_GetNextItem(LPCITEMIDLIST pidl)
 {
 	if(pidl)
 	{
-	   return (ITEMIDLIST*)(BYTE*)(((BYTE*)pidl) + pidl->mkid.cb);
+	   return (LPITEMIDLIST)(BYTE*)(((BYTE*)pidl) + pidl->mkid.cb);
 	}
 	else
 	   return NULL;
@@ -347,7 +347,7 @@ return pidl;
 UINT Pidl_GetSize(LPCITEMIDLIST pidl)
 {
 	UINT           cbTotal = 0;
-	ITEMIDLIST*   pidlTemp = (ITEMIDLIST*) pidl;
+	LPITEMIDLIST   pidlTemp = (LPITEMIDLIST)pidl;
 
 	if(pidlTemp)
 	{
@@ -415,12 +415,12 @@ int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
 	return 0;
 }
 
-bool CFileTreeCtrl::enumObjects(HTREEITEM hParentItem,IShellFolder* pParentFolder, ITEMIDLIST* pidlParent)
+bool CFileTreeCtrl::enumObjects(HTREEITEM hParentItem,IShellFolder* pParentFolder, LPITEMIDLIST pidlParent)
 {
 	IEnumIDList* pEnum;
 	if(SUCCEEDED(pParentFolder->EnumObjects(NULL, SHCONTF_NONFOLDERS |SHCONTF_FOLDERS|SHCONTF_INCLUDEHIDDEN, &pEnum)))
 	{
-		ITEMIDLIST* pidl;
+		LPITEMIDLIST pidl;
 		DWORD  dwFetched = 1;
 		TV_ITEM tvItem={0};
 		TV_INSERTSTRUCT   tvInsert={0};
@@ -445,7 +445,7 @@ bool CFileTreeCtrl::enumObjects(HTREEITEM hParentItem,IShellFolder* pParentFolde
 			nlverify ( SHGetPathFromIDList ( pidl, name ) );
 
 			// Save it
-			pItemInfo->displayName = tStrToUtf8(name);
+			pItemInfo->displayName = NLMISC::tStrToUtf8(name);
 
 			// Is a folder ?
 			bool folder = (pItemInfo->dwFlags&SFGAO_FOLDER) !=0;
@@ -720,7 +720,7 @@ bool CFileTreeCtrl::getCurrentFilename (std::string &result)
 	if (curSel)
 	{
 		CString str = _TreeCtrl.GetItemText (curSel);
-		result = tStrToUtf8(str);
+		result = NLMISC::tStrToUtf8(str);
 		return true;
 	}
 	return false;
diff --git a/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.h b/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.h
index bdfb5b050..c3729e0bf 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/file_tree_view.h
@@ -51,7 +51,7 @@ public:
 	bool create( const RECT& rect, CWnd* pParentWnd, UINT nID );
 	bool setRootDirectory (const char *dir);
 	void setArrangeMode (TArrange arrangeMode);
-	bool enumObjects (HTREEITEM hParentItem,IShellFolder* pParentFolder, ITEMIDLIST* pidlParent);
+	bool enumObjects (HTREEITEM hParentItem,IShellFolder* pParentFolder, LPITEMIDLIST pidlParent);
 	void doItemMenu (HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen);
 	void doClick (HWND hwndTreeView, HTREEITEM hItem);
 	void addExclusiveExtFilter (const char *ext);
diff --git a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
index d86cc21bd..8979d9237 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/form_dialog.cpp
@@ -832,7 +832,7 @@ BOOL CFormDialog::OnCommand(WPARAM wParam, LPARAM lParam)
 							smprintf (filter, 512, "%s Files (%s)|%s|All Files(*.*)|*.*|", typeName+i, ext.c_str(), ext.c_str());
 
 							// Open the dialog
-							CFileDialog dlgFile(TRUE, utf8ToTStr(ext), utf8ToTStr(ext), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, utf8ToTStr(filter), theApp.m_pMainWnd);
+						    CFileDialog dlgFile(TRUE, nlUtf8ToTStr(ext), nlUtf8ToTStr(ext), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, nlUtf8ToTStr(filter), theApp.m_pMainWnd);
 							if (dlgFile.DoModal () == IDOK)
 							{
 								combo->Combo.UpdateData ();
@@ -1316,16 +1316,16 @@ void IFormWidget::updateLabel ()
 					switch (where)
 					{
 					case UFormElm::ValueForm:
-						Label.SetWindowText(utf8ToTStr(SavedLabel + comp));
+						Label.SetWindowText(nlUtf8ToTStr(SavedLabel + comp));
 						break;
 					case UFormElm::ValueParentForm:
-						Label.SetWindowText(utf8ToTStr(SavedLabel + " (in parent form)" + comp));
+						Label.SetWindowText(nlUtf8ToTStr(SavedLabel + " (in parent form)" + comp));
 						break;
 					case UFormElm::ValueDefaultDfn:
-						Label.SetWindowText(utf8ToTStr(SavedLabel + " (default DFN value)" + comp));
+						Label.SetWindowText(nlUtf8ToTStr(SavedLabel + " (default DFN value)" + comp));
 						break;
 					case UFormElm::ValueDefaultType:
-						Label.SetWindowText(utf8ToTStr(SavedLabel + " (default TYPE value)" + comp));
+						Label.SetWindowText(nlUtf8ToTStr(SavedLabel + " (default TYPE value)" + comp));
 						break;
 					}
 				}
@@ -1352,18 +1352,18 @@ void IFormWidget::updateLabel ()
 						if (node->getForm () == doc->getFormPtr ())
 						{
 							// The node exist
-							Label.SetWindowText (utf8ToTStr(SavedLabel));
+							Label.SetWindowText(nlUtf8ToTStr(SavedLabel));
 						}
 						else
 						{
 							// The node exist in the parent form
-							Label.SetWindowText (utf8ToTStr(SavedLabel + " (in parent form)"));
+							Label.SetWindowText(nlUtf8ToTStr(SavedLabel + " (in parent form)"));
 						}
 					}	
 					else
 					{
 						// The node is empty
-						Label.SetWindowText (utf8ToTStr(SavedLabel + " (undefined)"));
+						Label.SetWindowText(nlUtf8ToTStr(SavedLabel + " (undefined)"));
 					}
 				}
 
@@ -1512,7 +1512,7 @@ void IFormWidget::onOpenSelected ()
 	std::string str2 = CPath::lookup (str, false, false);
 	if (str2.empty())
 		str2 = str;
-	theApp.OpenDocumentFile (utf8ToTStr(str2));
+	theApp.OpenDocumentFile(nlUtf8ToTStr(str2));
 }
 
 // ***************************************************************************
@@ -1569,7 +1569,7 @@ void CFormMemCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent,
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
+	Label.Create(nlUtf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -1691,7 +1691,7 @@ void CFormMemCombo::getFromDocument (CForm &form)
 		if (doc->getRootNode(getSlot ())->getValueByName (result, FormName, UFormElm::NoEval, NULL))
 		{
 			Combo.UpdateData ();
-			Combo.SetWindowText (utf8ToTStr(result));
+			Combo.SetWindowText(nlUtf8ToTStr(result));
 			Combo.UpdateData (FALSE);
 			updateLabel ();
 		}
@@ -1720,7 +1720,7 @@ void CFormMemCombo::getFromDocument (CForm &form)
 			CFormElmArray *arrayNode = safe_cast<CFormElmArray*> (node);
 			char label[512];
 			smprintf (label, 512, "%d", arrayNode->Elements.size ());
-			Combo.SetWindowText (utf8ToTStr(label));
+			Combo.SetWindowText(nlUtf8ToTStr(label));
 
 			if (arrayNode->getForm () == &form)
 				Label.SetWindowText (_T("Array size:"));
@@ -1751,7 +1751,7 @@ void CFormMemCombo::getFromDocument (CForm &form)
 		if (node)
 		{
 			CFormElmVirtualStruct *virtualNode = safe_cast<CFormElmVirtualStruct*> (node);
-			Combo.SetWindowText (utf8ToTStr(virtualNode->DfnFilename));
+			Combo.SetWindowText(nlUtf8ToTStr(virtualNode->DfnFilename));
 		}
 		else
 		{
@@ -1903,7 +1903,7 @@ void CFormCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, ui
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
+	Label.Create(nlUtf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -1921,7 +1921,7 @@ void CFormCombo::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, ui
 		Combo.InsertString (0, _T(""));
 		for (uint predef=0; predef<nodeType->Definitions.size(); predef++)
 		{
-			Combo.InsertString (predef+1, utf8ToTStr(nodeType->Definitions[predef].Label));
+			Combo.InsertString(predef + 1, nlUtf8ToTStr(nodeType->Definitions[predef].Label));
 		}
 	}
 
@@ -2088,7 +2088,7 @@ void CFormBigEdit::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent,
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
+	Label.Create(nlUtf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -2262,7 +2262,7 @@ void CColorEdit::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, ui
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
+	Label.Create(nlUtf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -2492,7 +2492,7 @@ void CListWidget::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, u
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
+	Label.Create(nlUtf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
@@ -2515,7 +2515,7 @@ void CListWidget::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, u
 
 void CListWidget::addColumn (const char *name)
 {
-	ListCtrl.insertColumn (0, utf8ToTStr(name));
+	ListCtrl.insertColumn(0, nlUtf8ToTStr(name));
 	ListCtrl.recalcColumn ();
 }
 
@@ -2566,7 +2566,7 @@ void CListWidget::getFromDocument (NLGEORGES::CForm &form)
 		string filename = form.getParentFilename (parent);
 
 		// Insert in the list
-		ListCtrl.ListCtrl.InsertItem (parent, utf8ToTStr(filename));
+		ListCtrl.ListCtrl.InsertItem(parent, nlUtf8ToTStr(filename));
 
 		ListCtrl.ListCtrl.UpdateData (FALSE);
 		updateLabel ();
@@ -2709,7 +2709,7 @@ void CListWidget::onOpenSelected ()
 		if (str != "")
 		{
 			// Look for the file
-			CString name = utf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
+			CString name = nlUtf8ToTStr(CPath::lookup(tStrToUtf8(str), false, false));
 			if (name.IsEmpty())
 				name = str;
 
@@ -2750,7 +2750,7 @@ void CIconWidget::create (DWORD wStyle, RECT &currentPos, CFormDialog *parent, u
 
 	// Create the type combo
 	parent->setStaticSize (currentPos);
-	Label.Create (utf8ToTStr(label), WS_VISIBLE, currentPos, parent);
+	Label.Create(nlUtf8ToTStr(label), WS_VISIBLE, currentPos, parent);
 	parent->initWidget (Label);
 	parent->getNextPosLabel (currentPos);
 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp
index 01f7b6f8e..3d374b4b1 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit_doc.cpp
@@ -182,8 +182,8 @@ bool CGeorgesEditDocForm::initDocument (const char *dfnName, bool newElement)
 
 	// Set file name and title
 	std::string name2 = toLower(NLMISC::CFile::getFilenameWithoutExtension(dfnName));
-	SetPathName (utf8ToTStr("*." + name2), FALSE);
-	SetTitle (utf8ToTStr("New " + name2 + " form"));
+	SetPathName(nlUtf8ToTStr("*." + name2), FALSE);
+	SetTitle(nlUtf8ToTStr("New " + name2 + " form"));
 
 	// TMp
 	if (newElement)
@@ -223,7 +223,7 @@ BOOL CGeorgesEditDocForm::OnNewDocument()
 		string defFilename = theApp.RootSearchPath;
 		defFilename += "*.dfn";
 
-		CFileDialog dlgFile(TRUE, _T("*.dfn"), utf8ToTStr(defFilename.c_str()), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, DfnFilter, theApp.m_pMainWnd);
+		CFileDialog dlgFile(TRUE, _T("*.dfn"), nlUtf8ToTStr(defFilename.c_str()), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, DfnFilter, theApp.m_pMainWnd);
 		if (dlgFile.DoModal () == IDOK)
 		{
 			if (initDocument(tStrToUtf8(dlgFile.GetFileName()).c_str(), true))
@@ -1331,7 +1331,7 @@ void CGeorgesEditDoc::setModifiedState (bool modified)
 		if ( (title.size ()>=2) && (title[title.size()-1] == '*') && (title[title.size()-2] == ' ') )
 		{
 			title.resize (title.size () - 2);
-			SetTitle (utf8ToTStr(title));
+			SetTitle(nlUtf8ToTStr(title));
 		}
 	}
 }
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_edit_view.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_edit_view.cpp
index e59fcb373..50a137006 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_edit_view.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_edit_view.cpp
@@ -295,7 +295,7 @@ void CGeorgesEditView::updateTab ()
 						// Init the tab
 						CGeorgesEditDocSub *child = parent->getChild (i);
 						int image = child->getItemImage (doc);
-						TabCtrl.InsertItem (i, utf8ToTStr(child->getName()), image);
+						TabCtrl.InsertItem(i, nlUtf8ToTStr(child->getName()), image);
 
 						// This is the selection ?
 						if (subObject == child)
diff --git a/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp b/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp
index 9e0b30f6e..d1c614834 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/georges_implementation.cpp
@@ -579,12 +579,12 @@ void CGeorgesImpl::LoadDocument( const std::string& _sxfullname )
 	AFX_MANAGE_STATE(AfxGetStaticModuleState());
 	try
 	{
-		theApp.OpenDocumentFile(utf8ToTStr(_sxfullname));
+		theApp.OpenDocumentFile(nlUtf8ToTStr(_sxfullname));
 	}
 	catch (const NLMISC::Exception &e)
 	{
 		std::string tmp = std::string(e.what()) + "(" + _sxfullname + ")";
-		theApp.m_pMainWnd->MessageBox(utf8ToTStr(tmp), _T("Georges_Lib"), MB_ICONERROR | MB_OK);
+		theApp.m_pMainWnd->MessageBox(nlUtf8ToTStr(tmp), _T("Georges_Lib"), MB_ICONERROR | MB_OK);
 	}
 }
 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp
index ee1385216..0ef0e4aad 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/header_dialog.cpp
@@ -109,7 +109,7 @@ BOOL CHeaderDialog::OnInitDialog()
 	ComboState.Create (WS_VISIBLE|CBS_DROPDOWNLIST|WS_TABSTOP, pos, this, CbState);
 	uint item;
 	for (item=0; item<CFileHeader::StateCount; item++)
-		ComboState.InsertString (-1, utf8ToTStr(CFileHeader::getStateString ((CFileHeader::TState)item)));
+		ComboState.InsertString(-1, nlUtf8ToTStr(CFileHeader::getStateString((CFileHeader::TState)item)));
 	ComboState.SetCurSel (0);
 	initWidget (ComboState);
 	getNextPos (currentPos);
diff --git a/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp b/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp
index 0de9b99b0..e43ed11f8 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/imagelist_ex.cpp
@@ -96,7 +96,7 @@ void CImageListEx::addResourceIcon (const char *filename)
 		int height = imageInfo.rcImage.bottom - imageInfo.rcImage.top;
 		
 		// Load the icon
-		HICON handle = (HICON) LoadImage (NULL, utf8ToTStr(filename), IMAGE_ICON, width, height, LR_COLOR|LR_LOADFROMFILE);
+		HICON handle = (HICON)LoadImage(NULL, nlUtf8ToTStr(filename), IMAGE_ICON, width, height, LR_COLOR | LR_LOADFROMFILE);
 		if (handle)
 		{
 			// Copy the icon
diff --git a/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp b/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp
index 7101680dd..8eeaebccc 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/left_view.cpp
@@ -109,14 +109,14 @@ void CLeftView::getSubObject (CGeorgesEditDocSub *subObject, HTREEITEM parent, H
 	if (!item)
 	{
 		int itemImage = subObject->getItemImage (GetDocument());
-		item = TreeCtrl.InsertItem (utf8ToTStr(subObject->getName()), itemImage, itemImage, parent);
+		item = TreeCtrl.InsertItem(nlUtf8ToTStr(subObject->getName()), itemImage, itemImage, parent);
 	}
 
 	// Set name
-	TreeCtrl.SetItemText (item, utf8ToTStr(subObject->getName()));
+	TreeCtrl.SetItemText(item, nlUtf8ToTStr(subObject->getName()));
 
 	// Set item data
-	TreeCtrl.SetItemData (item, (DWORD)subObject);
+	TreeCtrl.SetItemData (item, (DWORD_PTR)subObject);
 
 	// For each children
 	HTREEITEM child = TreeCtrl.GetChildItem (item);
diff --git a/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp b/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp
index 7239d0f69..9203fb605 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/main_frm.cpp
@@ -436,7 +436,7 @@ void CMainFrame::OnUpdateModules0(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[0].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (utf8ToTStr(name));
+		pCmdUI->SetText(nlUtf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[0].Activated);
 	}
 	else
@@ -464,7 +464,7 @@ void CMainFrame::OnUpdateModules1(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[1].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (utf8ToTStr(name));
+		pCmdUI->SetText(nlUtf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[1].Activated);
 	}
 	else
@@ -492,7 +492,7 @@ void CMainFrame::OnUpdateModules2(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[2].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (utf8ToTStr(name));
+		pCmdUI->SetText(nlUtf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[2].Activated);
 	}
 	else
@@ -520,7 +520,7 @@ void CMainFrame::OnUpdateModules3(CCmdUI* pCmdUI)
 		pCmdUI->Enable ();
 		string name;
 		theApp.PluginArray[3].PluginInterface->getPluginName (name);
-		pCmdUI->SetText (utf8ToTStr(name));
+		pCmdUI->SetText(nlUtf8ToTStr(name));
 		pCmdUI->SetCheck (theApp.PluginArray[3].Activated);
 	}
 	else
diff --git a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
index e0fb2d679..e06d72d0c 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
+++ b/code/ryzom/tools/leveldesign/georges_dll/memory_combo_box.h
@@ -59,7 +59,7 @@ public:
 	bool isWnd (const CWnd *wnd) const;
 	void enableAutoCompleteExtension (bool enable, const char * ext);
 
-	std::tstring			RegisterAdress;
+	NLMISC::tstring		RegisterAdress;
 	int					MemoryCount;
 	UINT				Id;
 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp b/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp
index 4577f6de8..247725513 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/output_console_dlg.cpp
@@ -98,7 +98,7 @@ void COutputConsoleDlg::outputString (const char *message)
 	{
 		int index = edit->LineIndex(edit->GetLineCount( )-1) + edit->LineLength(edit->GetLineCount( )-1);
 		edit->SetSel (index, index);
-		edit->ReplaceSel (utf8ToTStr(message));
+		edit->ReplaceSel(nlUtf8ToTStr(message));
 	}
 }
 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/settings_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/settings_dialog.cpp
index e57888595..55bd70607 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/settings_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/settings_dialog.cpp
@@ -103,13 +103,13 @@ void CSettingsDialog::OnOK()
 	UpdateData ();
 
 	// Make a config file
-	theApp.RootSearchPath = RootSearchPath;
-	theApp.TypeDfnSubDirectory = TypeDfnSubDirectory;
+	theApp.RootSearchPath = NLMISC::tStrToUtf8(RootSearchPath);
+	theApp.TypeDfnSubDirectory = NLMISC::tStrToUtf8(TypeDfnSubDirectory);
 	theApp.RememberListSize = RememberListSize;
 	theApp.StartExpanded = StartExpanded ? TRUE : FALSE;
 	theApp.MaxUndo = MaxUndo;
-	theApp.DefaultDfn = DefaultDfn;
-	theApp.DefaultType = DefaultType;
+	theApp.DefaultDfn = NLMISC::tStrToUtf8(DefaultDfn);
+	theApp.DefaultType = NLMISC::tStrToUtf8(DefaultType);
 	theApp.saveCfg ();
 	theApp.initCfg ();
 
@@ -118,30 +118,30 @@ void CSettingsDialog::OnOK()
 
 void CSettingsDialog::OnBrowse() 
 {
-	UpdateData ();
-	
+	UpdateData();
+
 	// Select a directory.
-	char path[MAX_PATH];
+	TCHAR path[MAX_PATH];
 
 	// Build the struct
 	BROWSEINFO info;
-	memset (&info, 0, sizeof (BROWSEINFO));
-	info.lpszTitle="Select the root search directory";
-	info.ulFlags=BIF_RETURNONLYFSDIRS;
+	memset(&info, 0, sizeof(BROWSEINFO));
+	info.lpszTitle = _T("Select the root search directory");
+	info.ulFlags = BIF_RETURNONLYFSDIRS;
 
 	// Select the path
 	LPITEMIDLIST list;
-	if (list=SHBrowseForFolder (&info))
+	if (list = SHBrowseForFolder(&info))
 	{
 		// Convert item into path string
-		BOOL bRet=SHGetPathFromIDList(list, path);
+		BOOL bRet = SHGetPathFromIDList(list, path);
 		if (bRet)
 		{
 			// Set the path
 			RootSearchPath = path;
 		}
-	}	
-	UpdateData (FALSE);
+	}
+	UpdateData(FALSE);
 }
 
 void CSettingsDialog::OnChangeRememberListSize() 
diff --git a/code/ryzom/tools/leveldesign/georges_dll/type_dialog.cpp b/code/ryzom/tools/leveldesign/georges_dll/type_dialog.cpp
index 53698ea8f..fac9c64bd 100644
--- a/code/ryzom/tools/leveldesign/georges_dll/type_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_dll/type_dialog.cpp
@@ -88,7 +88,7 @@ BOOL CTypeDialog::OnInitDialog()
 
 	// Create the type combo
 	setStaticSize (currentPos);
-	LabelType.Create ("Type:", WS_VISIBLE, currentPos, this);
+	LabelType.Create (_T("Type:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelType);
 	getNextPosLabel (currentPos);
 
@@ -101,7 +101,7 @@ BOOL CTypeDialog::OnInitDialog()
 	uint item;
 	ComboType.ResetContent ();
 	for (item=0; item<CType::TypeCount; item++)
-		ComboType.InsertString (-1, CType::getTypeName ((CType::TType)item));
+		ComboType.InsertString (-1, nlUtf8ToTStr(CType::getTypeName ((CType::TType)item)));
 
 	ComboType.SetCurSel (0);
 	initWidget (ComboType);
@@ -109,7 +109,7 @@ BOOL CTypeDialog::OnInitDialog()
 
 	// Create the type combo
 	setStaticSize (currentPos);
-	LabelUIType.Create ("User Interface:", WS_VISIBLE, currentPos, this);
+	LabelUIType.Create (_T("User Interface:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelUIType);
 	getNextPosLabel (currentPos);
 
@@ -123,59 +123,59 @@ BOOL CTypeDialog::OnInitDialog()
 
 	// Default value
 	setStaticSize (currentPos);
-	LabelDefault.Create ("Default value:", WS_VISIBLE, currentPos, this);
+	LabelDefault.Create (_T("Default value:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelDefault);
 	getNextPosLabel (currentPos);
 
 	setComboSize (currentPos, SmallWidget);
-	Default.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdDefault, GEORGES_EDIT_BASE_REG_KEY"\\Type Default MemCombo", theApp.RememberListSize);
+	Default.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdDefault, nlUtf8ToTStr(GEORGES_EDIT_BASE_REG_KEY"\\Type Default MemCombo"), theApp.RememberListSize);
 	initWidget (Default);
 	getNextPos (currentPos);
 
 	// Min value
 	setStaticSize (currentPos);
-	LabelMin.Create ("Min value:", WS_VISIBLE, currentPos, this);
+	LabelMin.Create (_T("Min value:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelMin);
 	getNextPosLabel (currentPos);
 
 	setComboSize (currentPos, SmallWidget);
-	Min.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdMin, GEORGES_EDIT_BASE_REG_KEY"\\Type Min MemCombo", theApp.RememberListSize);
+	Min.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdMin, nlUtf8ToTStr(GEORGES_EDIT_BASE_REG_KEY"\\Type Min MemCombo"), theApp.RememberListSize);
 	initWidget (Min);
 	getNextPos (currentPos);
 
 	// Max value
 	setStaticSize (currentPos);
-	LabelMax.Create ("Max value:", WS_VISIBLE, currentPos, this);
+	LabelMax.Create (_T("Max value:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelMax);
 	getNextPosLabel (currentPos);
 
 	setComboSize (currentPos, SmallWidget);
-	Max.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdMax, GEORGES_EDIT_BASE_REG_KEY"\\Type Max MemCombo", theApp.RememberListSize);
+	Max.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdMax, nlUtf8ToTStr(GEORGES_EDIT_BASE_REG_KEY"\\Type Max MemCombo"), theApp.RememberListSize);
 	initWidget (Max);
 	getNextPos (currentPos);
 
 	// Increment value
 	setStaticSize (currentPos);
-	LabelIncrement.Create ("Increment value:", WS_VISIBLE, currentPos, this);
+	LabelIncrement.Create (_T("Increment value:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelIncrement);
 	getNextPosLabel (currentPos);
 
 	setComboSize (currentPos, SmallWidget);
-	Increment.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdIncrement, GEORGES_EDIT_BASE_REG_KEY"\\Type Increment MemCombo", theApp.RememberListSize);
+	Increment.create (WS_CHILD|WS_TABSTOP, currentPos, this, EdIncrement, nlUtf8ToTStr(GEORGES_EDIT_BASE_REG_KEY"\\Type Increment MemCombo"), theApp.RememberListSize);
 	initWidget (Increment);
 	getNextColumn (currentPos);
 
 	// Predef list value
 	setStaticSize (currentPos);
-	LabelPreDef.Create ("Predefintion list:", WS_VISIBLE, currentPos, this);
+	LabelPreDef.Create (_T("Predefintion list:"), WS_VISIBLE, currentPos, this);
 	initWidget (LabelPreDef);
 	getNextPosLabel (currentPos);
 
 	setListSize (currentPos, SmallWidgetNotLimited, 250);
 	Predef.create (WS_TABSTOP, currentPos, this, LtPredef);
 	Predef.Dialog = this;
-	Predef.insertColumn (0, "Label");
-	Predef.insertColumn (1, "Value");
+	Predef.insertColumn (0, _T("Label"));
+	Predef.insertColumn (1, _T("Value"));
 	Predef.recalcColumn ();
 	initWidget (Predef);
 	getNextPos (currentPos);
@@ -356,7 +356,7 @@ void CTypeDialog::getFromDocument (const NLGEORGES::CType &type)
 		// Insert type string
 		ComboType.ResetContent ();
 		for (item=0; item<CType::TypeCount; item++)
-			ComboType.InsertString (-1, CType::getTypeName ((CType::TType)item));
+			ComboType.InsertString (-1, nlUtf8ToTStr(CType::getTypeName ((CType::TType)item)));
 
 		// Insert UI types
 		ComboUIType.ResetContent ();
@@ -364,7 +364,7 @@ void CTypeDialog::getFromDocument (const NLGEORGES::CType &type)
 		{
 			if (CType::uiCompatible (type.Type, (CType::TUI)item))
 			{
-				int index = ComboUIType.InsertString (-1, CType::getUIName ((CType::TUI)item));
+				int index = ComboUIType.InsertString(-1, nlUtf8ToTStr(CType::getUIName((CType::TUI)item)));
 				ComboUIType.SetItemData (index, item);
 				
 				if (item == (uint)type.UIType)
@@ -373,10 +373,10 @@ void CTypeDialog::getFromDocument (const NLGEORGES::CType &type)
 		}
 
 		ComboType.SetCurSel (type.Type);
-		Default.SetWindowText (type.Default.c_str());
-		Min.SetWindowText (type.Min.c_str());
-		Max.SetWindowText (type.Max.c_str());
-		Increment.SetWindowText (type.Increment.c_str());
+		Default.SetWindowText (nlUtf8ToTStr(type.Default));
+		Min.SetWindowText (nlUtf8ToTStr(type.Min));
+		Max.SetWindowText (nlUtf8ToTStr(type.Max));
+		Increment.SetWindowText (nlUtf8ToTStr(type.Increment));
 
 		// Disable some windows
 		bool number = (type.Type == UType::UnsignedInt) || (type.Type == UType::SignedInt) || (type.Type == UType::Double);
@@ -390,8 +390,8 @@ void CTypeDialog::getFromDocument (const NLGEORGES::CType &type)
 		for (predef=0; predef<type.Definitions.size(); predef++)
 		{
 			// Add the label and value
-			Predef.ListCtrl.InsertItem (predef, type.Definitions[predef].Label.c_str());
-			Predef.ListCtrl.SetItemText (predef, 1, type.Definitions[predef].Value.c_str());
+			Predef.ListCtrl.InsertItem (predef, nlUtf8ToTStr(type.Definitions[predef].Label));
+			Predef.ListCtrl.SetItemText (predef, 1, nlUtf8ToTStr(type.Definitions[predef].Value));
 		}
 	}
 }
@@ -431,71 +431,71 @@ void CTypeDialog::setUIToDocument ()
 
 void CTypeDialog::setDefaultToDocument ()
 {
-	CGeorgesEditDoc *doc = View->GetDocument ();
+	CGeorgesEditDoc *doc = View->GetDocument();
 	if (doc)
 	{
-		CGeorgesEditDocSub *current = doc->getSelectedObject ();
+		CGeorgesEditDocSub *current = doc->getSelectedObject();
 		if (current)
 		{
 			CString str;
 
-			Default.UpdateData ();
-			Default.GetWindowText (str);
+			Default.UpdateData();
+			Default.GetWindowText(str);
 
-			doc->modify (new CActionString (IAction::TypeDefault, str, *doc, "",  "",
-				doc->getLeftView ()->getCurrentSelectionId (), 0));
+			doc->modify(new CActionString(IAction::TypeDefault, nlTStrToUtf8(str), *doc, "", "",
+			    doc->getLeftView()->getCurrentSelectionId(), 0));
 		}
 	}
 }
 
 void CTypeDialog::setMinToDocument ()
 {
-	CGeorgesEditDoc *doc = View->GetDocument ();
+	CGeorgesEditDoc *doc = View->GetDocument();
 	if (doc)
 	{
-		CGeorgesEditDocSub *current = doc->getSelectedObject ();
+		CGeorgesEditDocSub *current = doc->getSelectedObject();
 		if (current)
 		{
 			CString str;
 
-			Min.UpdateData ();
-			Min.GetWindowText (str);
+			Min.UpdateData();
+			Min.GetWindowText(str);
 
-			doc->modify (new CActionString (IAction::TypeMin, str, *doc, "", "", 
-				doc->getLeftView ()->getCurrentSelectionId (), 0));
+			doc->modify(new CActionString(IAction::TypeMin, nlTStrToUtf8(str), *doc, "", "",
+			    doc->getLeftView()->getCurrentSelectionId(), 0));
 		}
 	}
 }
 
-void CTypeDialog::setMaxToDocument ()
+void CTypeDialog::setMaxToDocument()
 {
-	CGeorgesEditDoc *doc = View->GetDocument ();
+	CGeorgesEditDoc *doc = View->GetDocument();
 	if (doc)
 	{
-		CGeorgesEditDocSub *current = doc->getSelectedObject ();
+		CGeorgesEditDocSub *current = doc->getSelectedObject();
 		CString str;
 
-		Max.UpdateData ();
-		Max.GetWindowText (str);
+		Max.UpdateData();
+		Max.GetWindowText(str);
 
-		doc->modify (new CActionString (IAction::TypeMax, str, *doc, "", "", 
-			doc->getLeftView ()->getCurrentSelectionId (), 0));
+		doc->modify(new CActionString(IAction::TypeMax, nlTStrToUtf8(str), *doc, "", "",
+		    doc->getLeftView()->getCurrentSelectionId(), 0));
 	}
 }
 
-void CTypeDialog::setIncrementToDocument ()
+void CTypeDialog::setIncrementToDocument()
 {
-	CGeorgesEditDoc *doc = View->GetDocument ();
+	CGeorgesEditDoc *doc = View->GetDocument();
 	if (doc)
 	{
-		CGeorgesEditDocSub *current = doc->getSelectedObject ();
+		CGeorgesEditDocSub *current = doc->getSelectedObject();
 		CString str;
 
-		Increment.UpdateData ();
-		Increment.GetWindowText (str);
+		Increment.UpdateData();
+		Increment.GetWindowText(str);
 
-		doc->modify (new CActionString (IAction::TypeIncrement, str, *doc, "", "",
-			doc->getLeftView ()->getCurrentSelectionId (), 0));
+		doc->modify(new CActionString(IAction::TypeIncrement, nlTStrToUtf8(str), *doc, "", "",
+		    doc->getLeftView()->getCurrentSelectionId(), 0));
 	}
 }
 
diff --git a/code/ryzom/tools/leveldesign/georges_exe/georges_exe.cpp b/code/ryzom/tools/leveldesign/georges_exe/georges_exe.cpp
index 864a74bd7..5f4fa18ca 100644
--- a/code/ryzom/tools/leveldesign/georges_exe/georges_exe.cpp
+++ b/code/ryzom/tools/leveldesign/georges_exe/georges_exe.cpp
@@ -31,11 +31,7 @@
 
 using namespace std;
 
-
-int APIENTRY WinMain(HINSTANCE hInstance,
-                     HINSTANCE hPrevInstance,
-                     LPSTR     lpCmdLine,
-                     int       nCmdShow)
+int APIENTRY nltWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR lpCmdLine, int nCmdShow)
 {
 	// Init the NeL application context
 	NLMISC::CApplicationContext context;
@@ -48,7 +44,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
 		// Init ui
 		pGeorges->initUI(nCmdShow, true);
 
- 		string cmd = lpCmdLine;
+ 		string cmd = NLMISC::tStrToUtf8(lpCmdLine);
  		if(!cmd.empty())
  		{
  			nlinfo("Using command line '%s'", cmd.c_str());
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp
index 8b9092b4c..45a4985b9 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp
@@ -191,11 +191,11 @@ BOOL CPageBgFades::OnInitDialog()
 	for (uint i =0; i<32; ++i)
 	{
 		char tmp[128];
-		GetDlgItem(FILTER_NAMES[i])->SetWindowText(SoundDialog->EnvNames[i].Name.c_str());
-		sprintf(tmp, "%u", SoundDialog->FilterFades.FadeIns[i]);
-		GetDlgItem(FILTER_FADE_IN[i])->SetWindowText(tmp);
-		sprintf(tmp, "%u", SoundDialog->FilterFades.FadeOuts[i]);
-		GetDlgItem(FILTER_FADE_OUT[i])->SetWindowText(tmp);
+		GetDlgItem(FILTER_NAMES[i])->SetWindowText(nlUtf8ToTStr(SoundDialog->EnvNames[i].Name));
+		sprintf(tmp, "%u", (unsigned int)SoundDialog->FilterFades.FadeIns[i]);
+		GetDlgItem(FILTER_FADE_IN[i])->SetWindowText(nlUtf8ToTStr(tmp));
+		sprintf(tmp, "%u", (unsigned int)SoundDialog->FilterFades.FadeOuts[i]);
+		GetDlgItem(FILTER_FADE_OUT[i])->SetWindowText(nlUtf8ToTStr(tmp));
 	}
 
 	SoundDialog->getSoundPlugin()->getMixer()->setBackgroundFilterFades(SoundDialog->FilterFades);
@@ -209,20 +209,20 @@ BOOL CPageBgFades::OnCommand(WPARAM wParam, LPARAM lParam)
 	if (lParam != 0 && HIWORD(wParam) == EN_CHANGE)
 	{
 		int id = ::GetDlgCtrlID(HWND(lParam));
-		char tmp[1024];
+		TCHAR tmp[1024];
 
 		if (FILTER_FADE_IN_IDX.find(id) != FILTER_FADE_IN_IDX.end())
 		{
 			// this is a fade in value modified !
 			GetDlgItem(id)->GetWindowText(tmp, 1024);
-			SoundDialog->FilterFades.FadeIns[FILTER_FADE_IN_IDX[id]] = atoi(tmp);
+			SoundDialog->FilterFades.FadeIns[FILTER_FADE_IN_IDX[id]] = atoi(nlTStrToUtf8(tmp));
 			SoundDialog->getSoundPlugin()->getMixer()->setBackgroundFilterFades(SoundDialog->FilterFades);
 		}
 		else if (FILTER_FADE_OUT_IDX.find(id) != FILTER_FADE_OUT_IDX.end())
 		{
 			// this is a fade in value modified !
 			GetDlgItem(id)->GetWindowText(tmp, 1024);
-			SoundDialog->FilterFades.FadeOuts[FILTER_FADE_OUT_IDX[id]] = atoi(tmp);
+			SoundDialog->FilterFades.FadeOuts[FILTER_FADE_OUT_IDX[id]] = atoi(nlTStrToUtf8(tmp));
 			SoundDialog->getSoundPlugin()->getMixer()->setBackgroundFilterFades(SoundDialog->FilterFades);
 		}
 	}
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp
index 239c5b370..c844e7ca6 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp
@@ -421,8 +421,8 @@ BOOL CPageBgFlags::OnInitDialog()
 	const NLSOUND::UAudioMixer::TBackgroundFlags &flag = SoundDialog->getSoundPlugin()->getMixer()->getBackgroundFlags();
 	for (uint i=0; i<32; ++i)
 	{
-		GetDlgItem(FILTER_EDIT_NAME[i])->SetWindowText(SoundDialog->EnvNames[i].Name.c_str());
-		GetDlgItem(FILTER_SIM_NAME[i])->SetWindowText(SoundDialog->EnvNames[i].ShortName.c_str());
+		GetDlgItem(FILTER_EDIT_NAME[i])->SetWindowText(nlUtf8ToTStr(SoundDialog->EnvNames[i].Name));
+		GetDlgItem(FILTER_SIM_NAME[i])->SetWindowText(nlUtf8ToTStr(SoundDialog->EnvNames[i].ShortName));
 
 		static_cast<CButton*>(GetDlgItem(FILTER_SIM[i]))->SetCheck(flag.Flags[i] ? 1 : 0);
 	}
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp
index b3add5365..f36c3563b 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp
@@ -95,9 +95,9 @@ BOOL CPageComtext::OnCommand(WPARAM wParam, LPARAM lParam)
 		if (EDIT_ARG_IDX.find(id) != EDIT_ARG_IDX.end())
 		{
 			// need to update the var.
-			char tmp[1024];
+			TCHAR tmp[1024];
 			GetDlgItem(id)->GetWindowText(tmp, 1024);
-			SoundContext.Args[EDIT_ARG_IDX[id]] = atoi(tmp);
+			SoundContext.Args[EDIT_ARG_IDX[id]] = atoi(nlTStrToUtf8(tmp));
 		}
 	}
 	
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/georges_plugin_sound.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/georges_plugin_sound.cpp
index dd76b9f9e..a45b96f4e 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/georges_plugin_sound.cpp
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/georges_plugin_sound.cpp
@@ -49,14 +49,13 @@ __declspec( dllexport ) IEditPlugin *IGeorgesEditGetInterface (int version, NLGE
 		}
 		catch (const std::exception &e)
 		{
-			string reason = e.what();
-			MessageBox (NULL, reason.c_str(), "Sound plugin", MB_OK);
+			MessageBox (NULL, nlUtf8ToTStr(e.what()), _T("Sound plugin"), MB_OK);
 			return NULL;
 		}
 	}
 	else
 	{
-		MessageBox (NULL, "Plugin version invalid.", "Sound plugin for georges editor", MB_OK|MB_ICONEXCLAMATION);
+		MessageBox (NULL, _T("Plugin version invalid."), _T("Sound plugin for georges editor"), MB_OK|MB_ICONEXCLAMATION);
 		return NULL;
 	}
 
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/listener_view.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/listener_view.cpp
index 78d8d0ce8..867f0c7a2 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/listener_view.cpp
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/listener_view.cpp
@@ -68,7 +68,7 @@ bool CListenerView::registerClass()
 	}
 	catch (CResourceException* e)
 	{
-		  AfxMessageBox("Couldn't register class! (Already registered?)");
+		  AfxMessageBox(_T("Couldn't register class! (Already registered?)"));
 		  e->Delete();
 		  return false;
 	}
@@ -80,7 +80,7 @@ bool CListenerView::registerClass()
 	_VolumeCurve.CreatePen(PS_SOLID, 1, RGB(255, 0, 128)); 
 
 	_Font.CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, 
-					CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial");
+					CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Arial"));
 
 	return true;
 }
@@ -99,7 +99,7 @@ void CListenerView::init(CSoundPlugin* plugin, CRect& rect, CWnd* parent)
 	_OuterAngle = 360;
 	_InnerAngle = 360;
 
-	if (!Create((LPCTSTR) _WndClass, "Listener", WS_CHILD | WS_VISIBLE, rect, parent, ++_WndId))
+	if (!Create((LPCTSTR) _WndClass, _T("Listener"), WS_CHILD | WS_VISIBLE, rect, parent, ++_WndId))
 	{
 		throw exception("failed to create the listener view");
 	}
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_dialog.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_dialog.cpp
index 58ea1e9da..2b60fd098 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_dialog.cpp
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_dialog.cpp
@@ -239,7 +239,7 @@ void CSoundDialog::displayTime(uint32 msec)
 	uint min = sec / 60;
 	sec -= min * 60;
 	_snprintf(s, 256, "%02d:%02d", min, sec);
-	GetDlgItem(IDC_TIME)->SetWindowText(s);
+	GetDlgItem(IDC_TIME)->SetWindowText(nlUtf8ToTStr(s));
 }
 
 // ***************************************************************************
@@ -285,7 +285,7 @@ void CSoundDialog::updateInfo()
 
 	CPageBase::docChanged();
 
-	SetWindowText(_Name.c_str());
+	SetWindowText(nlUtf8ToTStr(_Name));
 
 	char s[256];
 /*	if (_Filename.empty())
@@ -342,7 +342,7 @@ void CSoundDialog::updateInfo()
 	msec -= sec * 1000;
 	sec -= min * 60;
 	_snprintf(s, 256, "%02d:%02d.%03d", min, sec, msec);
-	GetDlgItem(IDC_DURATION)->SetWindowText(s);
+	GetDlgItem(IDC_DURATION)->SetWindowText(nlUtf8ToTStr(s));
 
 	updateButton();
 }
@@ -361,7 +361,7 @@ bool CSoundDialog::getFileInfo(string& filename, uint& sampleRate, uint& sampleS
 	}
 
 	// Open the file 
-	HMMIO hmmio = mmioOpen((char*) path.c_str(), NULL, MMIO_READ | MMIO_DENYWRITE);
+	HMMIO hmmio = mmioOpen((LPTSTR)nlUtf8ToTStr(path), NULL, MMIO_READ | MMIO_DENYWRITE);
 	if (hmmio == NULL) 
 	{
 		return false;
@@ -484,7 +484,7 @@ void CSoundDialog::OnControlPlayback()
 
 		if (str == "*.sound")
 		{
-			MessageBox("You must save the file before playing it !", "Warning");
+			MessageBox(_T("You must save the file before playing it !"), _T("Warning"));
 			return;
 		}
 	}
diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_plugin.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_plugin.cpp
index e7c6b844c..47c8ed239 100644
--- a/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_plugin.cpp
+++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/sound_plugin.cpp
@@ -362,7 +362,7 @@ void CSoundPlugin::setActiveDocument(IEditDocument *pdoc)
 
 			if (invalid && !_InvalidSound)
 			{
-				MessageBox(NULL, "This sound contains an infinite recursion !", "Sound Error", MB_ICONERROR);
+				MessageBox(NULL, _T("This sound contains an infinite recursion !"), _T("Sound Error"), MB_ICONERROR);
 			}
 
 			// pre-create the sound to force loading any missing sample bank (thus avoiding unwanted message box)
@@ -410,7 +410,7 @@ void CSoundPlugin::setActiveDocument(IEditDocument *pdoc)
 						message += (*first)+"\n";
 				}
 
-				MessageBox(NULL, message.c_str(), "Sound incomplete", MB_ICONWARNING);
+				MessageBox(NULL, nlUtf8ToTStr(message), _T("Sound incomplete"), MB_ICONWARNING);
 			}
 			
 
@@ -474,12 +474,12 @@ void CSoundPlugin::onCreateDocument(IEditDocument *document)
 void CSoundPlugin::createNew()
 {
 	AFX_MANAGE_STATE(AfxGetStaticModuleState());
-	char BASED_CODE szFilter[] = "Sound (*.sound)|*.sound|All Files (*.*)|*.*||";
-	CFileDialog fileDlg(FALSE, ".sound", "*.sound", OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter);
+	TCHAR BASED_CODE szFilter[] = _T("Sound (*.sound)|*.sound|All Files (*.*)|*.*||");
+	CFileDialog fileDlg(FALSE, _T(".sound"), _T("*.sound"), OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter);
 
 	if (fileDlg.DoModal() == IDOK)
 	{
-		string filename = (const char*) fileDlg.GetPathName();
+		string filename = NLMISC::tStrToUtf8(fileDlg.GetPathName());
 		_GlobalInterface->createDocument("sound.dfn", filename.c_str());
 	}
 }
@@ -585,8 +585,7 @@ void CSoundPlugin::play(std::string &filename)
 	}
 	catch (ESoundDriver& e)
 	{
-		string reason = e.what();
-		MessageBox (NULL, reason.c_str(), "Sound plugin", MB_OK);
+		MessageBox(NULL, nlUtf8ToTStr(e.what()), _T("Sound plugin"), MB_OK);
 	}
 }
 

From 09225503fce5fdb61b17b73952b08cff579cc34c Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 07:51:59 +0800
Subject: [PATCH 50/75] Cleaning up unicode conversion

---
 .../tools/misc/message_box/message_box.cpp    |  4 +-
 .../multi_cd_setup_fix/multi_cd_setup_fix.cpp |  2 +-
 .../world_editor/builder_zone.cpp             | 24 +++++-----
 .../world_editor/dialog_properties.cpp        | 33 +++++++------
 .../world_editor/world_editor/display.cpp     |  4 +-
 .../world_editor/external_editor.cpp          |  2 +-
 .../world_editor/find_primitive_dlg.cpp       | 18 +++----
 .../world_editor/generate_dlg.cpp             |  2 +-
 .../world_editor/imagelist_ex.cpp             |  2 +-
 .../world_editor/world_editor/main_frm.cpp    | 32 ++++++-------
 .../world_editor/world_editor/my_list_box.cpp |  2 +-
 .../world_editor/world_editor/name_dlg.cpp    | 18 +++----
 .../primitive_configuration_dlg.cpp           |  2 +-
 .../world_editor/project_settings.cpp         | 10 ++--
 .../world_editor/world_editor/tools_logic.cpp | 10 ++--
 .../world_editor/world_editor/tools_zone.cpp  | 48 +++++++++----------
 .../world_editor/type_manager_dlg.cpp         | 10 ++--
 .../world_editor/type_sel_dlg.cpp             |  4 +-
 .../world_editor/world_editor.cpp             | 12 ++---
 .../world_editor/world_editor_doc.cpp         |  6 +--
 20 files changed, 123 insertions(+), 122 deletions(-)

diff --git a/code/nel/tools/misc/message_box/message_box.cpp b/code/nel/tools/misc/message_box/message_box.cpp
index ae8866a16..64a4b93d7 100644
--- a/code/nel/tools/misc/message_box/message_box.cpp
+++ b/code/nel/tools/misc/message_box/message_box.cpp
@@ -15,11 +15,13 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <windows.h>
+#include <tchar.h>
+
 #include <string>
 #include <stdio.h>
 
 using namespace std;
-int APIENTRY _tWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR /* lpCmdLine */, int /* nCmdShow */)
+int APIENTRY _tWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR lpCmdLine, int /* nCmdShow */)
 {
 	char *filename;
 	if (filename = strstr (lpCmdLine, "-f "))
diff --git a/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp b/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
index 9d9e9b590..ee9b4b9fe 100644
--- a/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
+++ b/code/nel/tools/misc/multi_cd_setup_fix/multi_cd_setup_fix.cpp
@@ -40,7 +40,7 @@ void pump ()
 		DispatchMessage(&msg);
 	}
 }
-int APIENTRY _tWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPTSTR /* lpCmdLine */, int /* nCmdShow */)
+int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPTSTR /* lpCmdLine */, int /* nCmdShow */)
 {
 	// Windows
 	HWND hwnd = CreateDialog (hInstance, MAKEINTRESOURCE(IDD_WAIT), NULL, MyDialogProc);
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/builder_zone.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/builder_zone.cpp
index c380db296..5e6119d89 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/builder_zone.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/builder_zone.cpp
@@ -130,10 +130,10 @@ bool CDataBase::init (const string &Path, CZoneBank &zb)
 	string sDirBackup = NLMISC::CPath::getCurrentPath();
 
 	// "Path" can be relative to the doc path so we have to be first in the doc path
-	string s2 = NLMISC::CFile::getPath (tStrToUtf8(getMainFrame()->getDocument()->GetPathName()));
+	string s2 = NLMISC::CFile::getPath(NLMISC::tStrToUtf8(getMainFrame()->getDocument()->GetPathName()));
 	NLMISC::CPath::setCurrentPath(s2.c_str());
 	string ss = NLMISC::CPath::getFullPath(Path);
-	NLMISC::CPath::setCurrentPath (ss.c_str());
+	NLMISC::CPath::setCurrentPath(ss.c_str());
 
 	uint32 i, m, n, o, p;
 	uint8 k, l;
@@ -623,7 +623,7 @@ bool CBuilderZone::refresh ()
 			{
 				unload (_ZoneRegionSelected);
 				std::string msg = NLMISC::toString("Cannot add this zone :\n%s", error.c_str());
-				MessageBox (NULL, utf8ToTStr(msg), _T("Error"), MB_ICONERROR|MB_OK);
+				MessageBox (NULL, nlUtf8ToTStr(msg), _T("Error"), MB_ICONERROR|MB_OK);
 				return false;
 			}
 
@@ -1600,25 +1600,25 @@ bool CBuilderZone::initZoneBank (const string &sPathName)
 {
 	// TODO: replace by NeL methods
 	TCHAR sDirBackup[512];
-	GetCurrentDirectory (512, sDirBackup);
-	SetCurrentDirectory (utf8ToTStr(sPathName));
+	GetCurrentDirectory(512, sDirBackup);
+	SetCurrentDirectory(nlUtf8ToTStr(sPathName));
 	WIN32_FIND_DATA findData;
 	HANDLE hFind;
-	hFind = FindFirstFile (_T("*.ligozone"), &findData);
-	
+	hFind = FindFirstFile(_T("*.ligozone"), &findData);
+
 	while (hFind != INVALID_HANDLE_VALUE)
 	{
 		// If the name of the file is not . or .. then its a valid entry in the DataBase
-		if (!((_tcscmp (findData.cFileName, _T(".")) == 0) || (_tcscmp (findData.cFileName, _T("..")) == 0)))
+		if (!((_tcscmp(findData.cFileName, _T(".")) == 0) || (_tcscmp(findData.cFileName, _T("..")) == 0)))
 		{
 			string error;
-			if (!_ZoneBank.addElement (tStrToUtf8(findData.cFileName), error))
-				theApp.errorMessage (error.c_str());
+			if (!_ZoneBank.addElement(NLMISC::tStrToUtf8(findData.cFileName), error))
+				theApp.errorMessage(error.c_str());
 		}
-		if (FindNextFile (hFind, &findData) == 0)
+		if (FindNextFile(hFind, &findData) == 0)
 			break;
 	}
-	SetCurrentDirectory (sDirBackup);
+	SetCurrentDirectory(sDirBackup);
 	return true;
 }
 
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/dialog_properties.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/dialog_properties.cpp
index 2b0a88527..5a4ebc39e 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/dialog_properties.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/dialog_properties.cpp
@@ -352,7 +352,7 @@ void CDialogProperties::addWidget (const CPrimitiveClass::CParameter &parameter,
 		string Name = widget.Parameter.Name;
 
 		// Create a check box
-		nlverify (widget.CheckBox.Create (utf8ToTStr(Name), BS_3STATE|WS_VISIBLE|WS_TABSTOP|(enabled?0:WS_DISABLED), widgetPos, &m_PropertyCont, id));
+		nlverify(widget.CheckBox.Create(nlUtf8ToTStr(Name), BS_3STATE | WS_VISIBLE | WS_TABSTOP | (enabled ? 0 : WS_DISABLED), widgetPos, &m_PropertyCont, id));
 		widget.CheckBox.SetFont (GetFont ());
 	}
 	else if (widget.Parameter.Type == CPrimitiveClass::CParameter::ConstString)
@@ -522,7 +522,7 @@ void CDialogProperties::addWidget (const CPrimitiveClass::CParameter &parameter,
 			
 			for (vector<string>::iterator	it=PathList.begin(), itEnd=PathList.end(); it!=itEnd; ++it)
 			{
-				widget.ListEditBox.StringSelectComboBox.InsertString( -1, utf8ToTStr(*it));
+				widget.ListEditBox.StringSelectComboBox.InsertString( -1, nlUtf8ToTStr(*it));
 			}
 		}
 
@@ -549,7 +549,7 @@ void CDialogProperties::addWidget (const CPrimitiveClass::CParameter &parameter,
 				
 				for (vector<string>::iterator	it=PathList.begin(), itEnd=PathList.end(); it!=itEnd; ++it)
 				{
-					widget.ListEditBox.StringSelectComboBox.InsertString( -1, utf8ToTStr(*it));
+					widget.ListEditBox.StringSelectComboBox.InsertString(-1, nlUtf8ToTStr(*it));
 				}
 			}
 		}
@@ -915,11 +915,11 @@ bool CDialogProperties::CWidget::fromParameter (const IProperty *property, const
 						updateBoolean ();
 						break;
 					case  CPrimitiveClass::CParameter::ConstString:
-						if (Parameter.Editable || ComboBox.SelectString(-1, utf8ToTStr(propString->String)) == CB_ERR)
+						if (Parameter.Editable || ComboBox.SelectString(-1, nlUtf8ToTStr(propString->String)) == CB_ERR)
 						{
-							ComboBox.SetWindowText(utf8ToTStr(propString->String));
-							ComboBox.InsertString( -1, utf8ToTStr(propString->String));
-							ComboBox.SelectString(-1, utf8ToTStr(propString->String));
+							ComboBox.SetWindowText(nlUtf8ToTStr(propString->String));
+							ComboBox.InsertString(-1, nlUtf8ToTStr(propString->String));
+							ComboBox.SelectString(-1, nlUtf8ToTStr(propString->String));
 						}
 						OriginalString = propString->String.c_str();
 						updateCombo ();
@@ -953,7 +953,7 @@ bool CDialogProperties::CWidget::fromParameter (const IProperty *property, const
 							updateBoolean ();
 							break;
 						case  CPrimitiveClass::CParameter::ConstString:
-							ComboBox.SelectString(-1, utf8ToTStr(result));
+							ComboBox.SelectString(-1, nlUtf8ToTStr(result));
 							OriginalString = result.c_str();
 							updateCombo ();
 							break;
@@ -1282,7 +1282,7 @@ void CDialogProperties::CWidget::updateCombo ()
 		DialogProperties->setDefaultValue (this, value);
 		if (value != "")
 		{
-			int index = ComboBox.FindString (-1, utf8ToTStr(value));
+			int index = ComboBox.FindString(-1, nlUtf8ToTStr(value));
 			if (index != CB_ERR)
 				ComboBox.SetCurSel (index);
 		}
@@ -1621,14 +1621,14 @@ BOOL CDialogProperties::OnCommand(WPARAM wParam, LPARAM lParam)
 					/* todo hulud remove
 					CString oldValue;
 					widget->EditBox.GetWindowText (oldValue);*/
-					CFileDialogEx dialog (BASE_REGISTRY_KEY, _T("default"), TRUE, utf8ToTStr(widget->Parameter.FileExtension), NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
-						utf8ToTStr(widget->Parameter.FileExtension+" (*."+widget->Parameter.FileExtension+")|*."+widget->Parameter.FileExtension+"|All Files (*.*)|*.*||"), getMainFrame ());
+				    CFileDialogEx dialog(BASE_REGISTRY_KEY, _T("default"), TRUE, nlUtf8ToTStr(widget->Parameter.FileExtension), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+				        nlUtf8ToTStr(widget->Parameter.FileExtension + " (*." + widget->Parameter.FileExtension + ")|*." + widget->Parameter.FileExtension + "|All Files (*.*)|*.*||"), getMainFrame());
 
 					TCHAR temp[MAX_PATH];
 
 					if (!widget->Parameter.Folder.empty())
 					{
-						_tcscpy_s(temp, MAX_PATH, utf8ToTStr(widget->Parameter.Folder));
+					    _tcscpy_s(temp, MAX_PATH, nlUtf8ToTStr(widget->Parameter.Folder));
 						dialog.m_ofn.lpstrInitialDir = temp;
 					}
 
@@ -1636,7 +1636,7 @@ BOOL CDialogProperties::OnCommand(WPARAM wParam, LPARAM lParam)
 					{
 						CString str;
 						str = dialog.GetFileTitle();
-						setWindowTextUTF8 (widget->EditBox, tStrToUtf8(str));
+						setWindowTextUTF8 (widget->EditBox, NLMISC::tStrToUtf8(str));
 
 			/* todo hulud remove
 						if ((const char*)oldValue != str)
@@ -2305,7 +2305,7 @@ void CDialogProperties::rebuildDialog ()
 	m_ScrollBar.MoveWindow(&scrollRect, TRUE);
 
 	// set the name of the dlg according to displayed class
-	SetWindowText( CString(_T("Properties for : ")) + utf8ToTStr(windowName) );
+	SetWindowText(CString(_T("Properties for : ")) + nlUtf8ToTStr(windowName));
 
 //	// JC: added scrolling properties
 //	::CRect clientRect;
@@ -2982,13 +2982,12 @@ void CDialogProperties::SelectFolder(CWidget *widget)
 
 	LPITEMIDLIST pidlRoot = NULL;
 	LPSHELLFOLDER desktop;
-	ULONG ulDummy;
 	
 	SHGetDesktopFolder (&desktop);
 	
 	if (widget->Parameter.Folder != "")
 	{
-		desktop->ParseDisplayName (NULL, NULL, utf8ToTStr(widget->Parameter.Folder), &ulDummy, &pidlRoot, &ulDummy);
+		desktop->ParseDisplayName(NULL, NULL, (LPTSTR)nlUtf8ToTStr(widget->Parameter.Folder), NULL, &pidlRoot, NULL);
 	}
 	bi.pidlRoot = pidlRoot;
 	
@@ -3454,7 +3453,7 @@ void CMyComboBox::reloadData()
 		SetRedraw(FALSE);
 		InsertString(-1, _T(""));
 		for (vector<string>::iterator it=_data.begin(), itEnd=_data.end(); it!=itEnd; ++it)
-			InsertString(-1, utf8ToTStr(*it));
+			InsertString(-1, nlUtf8ToTStr(*it));
 		loaded = true;
 		SetRedraw(TRUE);
 		if(n != CB_ERR) SelectString(-1, s);
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp
index 5f149f01e..7b0b9df23 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/display.cpp
@@ -318,7 +318,7 @@ void CDisplay::init (CMainFrame *pMF)
 		}
 	}
 
-	SetCurrentDirectory (utf8ToTStr(pMF->_ExeDir));
+	SetCurrentDirectory (nlUtf8ToTStr(pMF->_ExeDir));
 }
 
 // ***************************************************************************
@@ -3554,7 +3554,7 @@ void CDisplay::DrawCollisionTexture(sint32 count, float x1, float y1)
 				string dir = getDocument ()->getDataDir ();
 				if (dir.empty()) dir = _MainFrame->_ExeDir;
 				dir += "\\collisionmap\\";
-				SetCurrentDirectory (utf8ToTStr(dir));
+				SetCurrentDirectory(nlUtf8ToTStr(dir));
 
 				if(NLMISC::CFile::fileExists(Name+".tga") || NLMISC::CFile::fileExists(Name+".png"))
 				{
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/external_editor.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/external_editor.cpp
index 8e20608e6..be0f50a08 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/external_editor.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/external_editor.cpp
@@ -58,7 +58,7 @@ bool EditExternalText (const std::string &editor, std::string &text, const std::
 		}
 
 		// Hide the file
-		SetFileAttributes (utf8ToTStr(tempFilename), FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
+		SetFileAttributes(nlUtf8ToTStr(tempFilename), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
 
 		// Open the temp file with a text editor
 		if (saved)
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/find_primitive_dlg.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/find_primitive_dlg.cpp
index 9cf7e2dee..8dd112873 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/find_primitive_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/find_primitive_dlg.cpp
@@ -112,7 +112,7 @@ void CFindPrimitiveDlg::OnFindNext()
 //					||	(	_Locator.Primitive->getPropertyByName ("selected", property)
 					||	(	getPrimitiveEditor(_Locator.Primitive)->getSelected()))
 //						&&	property)	)
-				&&	_Locator.Primitive->getPropertyByName (tStrToUtf8(Property), property)
+				&&	_Locator.Primitive->getPropertyByName (NLMISC::tStrToUtf8(Property), property)
 				&&	property)
 			{
 				// Kind of primitive ?
@@ -120,7 +120,7 @@ void CFindPrimitiveDlg::OnFindNext()
 				if (propString)
 				{
 					// Good value ?
-					if	(propString->String.find(tStrToUtf8(Value))!=std::string::npos)
+					if (propString->String.find(NLMISC::tStrToUtf8(Value)) != std::string::npos)
 					{
 						found = true;
 					}
@@ -135,7 +135,7 @@ void CFindPrimitiveDlg::OnFindNext()
 						uint i;
 						for (i=0; i<propStringArray->StringArray.size (); i++)
 						{
-							if	(propStringArray->StringArray[i].find(tStrToUtf8(Value))!=std::string::npos)
+							if (propStringArray->StringArray[i].find(NLMISC::tStrToUtf8(Value)) != std::string::npos)
 							{
 								found = true;
 							}
@@ -230,7 +230,7 @@ void CFindPrimitiveDlg::replace(bool all)
 //					||	(	_Locator.Primitive->getPropertyByName ("selected", property)
 					||	(	getPrimitiveEditor(_Locator.Primitive)->getSelected()))
 //						&&	property)	)
-				&&	_Locator.Primitive->getPropertyByName (tStrToUtf8(Property), property)
+			    && _Locator.Primitive->getPropertyByName(NLMISC::tStrToUtf8(Property), property)
 				&&	property	)
 			{
 				// Kind of primitive ?
@@ -238,14 +238,14 @@ void CFindPrimitiveDlg::replace(bool all)
 				if	(propString)
 				{
 					// Good value ?
-					if	(propString->String.find(tStrToUtf8(Value))!=std::string::npos)
+					if (propString->String.find(NLMISC::tStrToUtf8(Value)) != std::string::npos)
 					{
 						if	(!firstTime	&&	!all)
 							break;
 
 						CString	tmp(propString->String.c_str());
 						tmp.Replace(Value, ReplaceText);
-						doc->addModification (new CActionSetPrimitivePropertyString (_Locator, tStrToUtf8(Property), tStrToUtf8(tmp), false));
+						doc->addModification(new CActionSetPrimitivePropertyString(_Locator, NLMISC::tStrToUtf8(Property), NLMISC::tStrToUtf8(tmp), false));
 						doc->addModification (new CActionSelect (_Locator));
 						
 						firstTime=false;
@@ -265,7 +265,7 @@ void CFindPrimitiveDlg::replace(bool all)
 						for (i=0; i<propStringArray->StringArray.size (); i++)
 						{
 							//	todo.
-							if	(propStringArray->StringArray[i].find(tStrToUtf8(Value))!=std::string::npos)
+							if (propStringArray->StringArray[i].find(NLMISC::tStrToUtf8(Value)) != std::string::npos)
 							{
 								if	(	!firstTime
 									&&	!all)
@@ -281,7 +281,7 @@ void CFindPrimitiveDlg::replace(bool all)
 										newStrings=propStringArray->StringArray;
 										firstChange=false;
 									}
-									newStrings[i] = tStrToUtf8(tmp);
+									newStrings[i] = NLMISC::tStrToUtf8(tmp);
 								}
 								firstTime=false;
 							}
@@ -290,7 +290,7 @@ void CFindPrimitiveDlg::replace(bool all)
 
 						if (!firstChange)	//	have to make a change
 						{
-							doc->addModification (new CActionSetPrimitivePropertyStringArray (_Locator, tStrToUtf8(Property), newStrings, false));
+							doc->addModification(new CActionSetPrimitivePropertyStringArray(_Locator, NLMISC::tStrToUtf8(Property), newStrings, false));
 							doc->addModification (new CActionSelect (_Locator));
 						}
 
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/generate_dlg.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/generate_dlg.cpp
index e4c5d0d8e..88131ab60 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/generate_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/generate_dlg.cpp
@@ -75,7 +75,7 @@ BOOL CGenerateDlg::OnInitDialog()
 	
 	// TODO: Add extra initialization here
 	for (uint32 i = 0; i < AllMaterials.size(); ++i)
-		ComboMaterial.InsertString(-1, utf8ToTStr(AllMaterials[i]));
+		ComboMaterial.InsertString(-1, nlUtf8ToTStr(AllMaterials[i]));
 
 	ComboMaterial.SetCurSel (0);
 
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/imagelist_ex.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/imagelist_ex.cpp
index a24ef1c07..f00181879 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/imagelist_ex.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/imagelist_ex.cpp
@@ -100,7 +100,7 @@ void CImageListEx::addResourceIcon (const char *filename)
 		int height = imageInfo.rcImage.bottom - imageInfo.rcImage.top;
 		
 		// Load the icon
-		HICON handle = (HICON) LoadImage (NULL, utf8ToTStr(filename), IMAGE_ICON, width, height, LR_COLOR|LR_LOADFROMFILE);
+		HICON handle = (HICON) LoadImage (NULL, nlUtf8ToTStr(filename), IMAGE_ICON, width, height, LR_COLOR|LR_LOADFROMFILE);
 		if (handle)
 		{
 			// Copy the icon
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/main_frm.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/main_frm.cpp
index c17d81198..101903b21 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/main_frm.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/main_frm.cpp
@@ -759,11 +759,11 @@ void CMainFrame::displayStatusBarInfo ()
 	string text;
 	if (dispWnd->getActionHelp (text))
 	{
-		m_wndStatusBar.SetPaneText (0, utf8ToTStr(text));
+		m_wndStatusBar.SetPaneText(0, nlUtf8ToTStr(text));
 	}
 	else
 	{
-		m_wndStatusBar.SetPaneText (0, utf8ToTStr(sTmp));
+		m_wndStatusBar.SetPaneText(0, nlUtf8ToTStr(sTmp));
 	}
 	//for (uint32 i = sTmp.size(); i < 10; ++i)
 	//	sTmp += " ";
@@ -771,12 +771,12 @@ void CMainFrame::displayStatusBarInfo ()
 	// Write zone reference name 
 	if (dispWnd->getActionText (text))
 	{
-		m_wndStatusBar.SetPaneText (1, utf8ToTStr(text));
+		m_wndStatusBar.SetPaneText(1, nlUtf8ToTStr(text));
 	}
 	else
 	{
 		sTmp = _ZoneBuilder->getZoneName (x, y);
-		m_wndStatusBar.SetPaneText (1, utf8ToTStr(sTmp));
+		m_wndStatusBar.SetPaneText(1, nlUtf8ToTStr(sTmp));
 	}
 
 	// Write coordinates
@@ -784,15 +784,15 @@ void CMainFrame::displayStatusBarInfo ()
 	sprintf(temp, "(%.3f , %.3f)", v.x, v.y);
 	sTmp = temp;
 //	sTmp = "( " + toString(v.x) + " , " + toString(v.y) + " )";
-	m_wndStatusBar.SetPaneText (2, utf8ToTStr(sTmp));
+	m_wndStatusBar.SetPaneText(2, nlUtf8ToTStr(sTmp));
 
 	// Write rot
 	sTmp = "Rot(" + toString(_ZoneBuilder->getRot(x, y)) + ")";
-	m_wndStatusBar.SetPaneText (3, utf8ToTStr(sTmp));
+	m_wndStatusBar.SetPaneText(3, nlUtf8ToTStr(sTmp));
 
 	// Write flip
 	sTmp = "Flip(" + toString(_ZoneBuilder->getFlip(x, y)) + ")";
-	m_wndStatusBar.SetPaneText (4, utf8ToTStr(sTmp));
+	m_wndStatusBar.SetPaneText(4, nlUtf8ToTStr(sTmp));
 
 	// Write selection
 	if (Selection.size ())
@@ -804,7 +804,7 @@ void CMainFrame::displayStatusBarInfo ()
 	}
 	else
 		sTmp = "No selected primitive";
-	m_wndStatusBar.SetPaneText (5, utf8ToTStr(sTmp));
+	m_wndStatusBar.SetPaneText(5, nlUtf8ToTStr(sTmp));
 
 	// Write path of selected primitive
 	if (Selection.size())
@@ -812,14 +812,14 @@ void CMainFrame::displayStatusBarInfo ()
 	else
 		sTmp.clear();
 	
-	m_wndStatusBar.SetPaneText (6, utf8ToTStr(sTmp));
+	m_wndStatusBar.SetPaneText(6, nlUtf8ToTStr(sTmp));
 }
 
 // ***************************************************************************
 
 void CMainFrame::displayInfo (const std::string &info)
 {
-	m_wndStatusBar.SetPaneText (6, utf8ToTStr(info));
+	m_wndStatusBar.SetPaneText(6, nlUtf8ToTStr(info));
 }
 
 // ***************************************************************************
@@ -858,7 +858,7 @@ void CMainFrame::uninit ()
 	}
 	catch (const Exception& e)
 	{
-		MessageBox (utf8ToTStr(e.what()), _T("Warning"));
+		MessageBox(nlUtf8ToTStr(e.what()), _T("Warning"));
 	}
 }
 
@@ -2710,7 +2710,7 @@ void CMainFrame::createContextMenu (CWnd *parent, const CPoint &point, bool tran
 				// For each child, add a create method
 				for (uint i=0; i<primClass->DynamicChildren.size (); i++)
 				{
-					pMenu->AppendMenu (MF_STRING, ID_EDIT_CREATE_BEGIN+i, utf8ToTStr("Add " + primClass->DynamicChildren[i].ClassName));
+					pMenu->AppendMenu(MF_STRING, ID_EDIT_CREATE_BEGIN + i, nlUtf8ToTStr("Add " + primClass->DynamicChildren[i].ClassName));
 				}
 			}
 
@@ -2723,7 +2723,7 @@ void CMainFrame::createContextMenu (CWnd *parent, const CPoint &point, bool tran
 				// For each child, add a create method
 				for (uint i=0; i<primClass->GeneratedChildren.size (); i++)
 				{
-					pMenu->AppendMenu (MF_STRING, ID_EDIT_GENERATE_BEGIN+i, utf8ToTStr("Generate "+primClass->GeneratedChildren[i].ClassName));
+					pMenu->AppendMenu(MF_STRING, ID_EDIT_GENERATE_BEGIN + i, nlUtf8ToTStr("Generate " + primClass->GeneratedChildren[i].ClassName));
 				}
 			}
 
@@ -2747,7 +2747,7 @@ void CMainFrame::createContextMenu (CWnd *parent, const CPoint &point, bool tran
 					for (i=0; i<filenames.size (); i++)
 					{
 						// Add a menu entry
-						pMenu->AppendMenu (MF_STRING, ID_EDIT_OPEN_FILE_BEGIN+i, utf8ToTStr("Open " + NLMISC::CFile::getFilename (filenames[i])));
+						pMenu->AppendMenu(MF_STRING, ID_EDIT_OPEN_FILE_BEGIN + i, nlUtf8ToTStr("Open " + NLMISC::CFile::getFilename(filenames[i])));
 					}
 				}
 			}
@@ -3717,7 +3717,7 @@ void CMainFrame::OnProjectForceiduniqueness()
 	// End modifications
 	doc->endModification ();
 
-	AfxMessageBox(utf8ToTStr(NLMISC::toString("%u ids checked, %u non unique ID regenerated", ids.size()+nonUnique.size(), nonUnique.size())), MB_OK);
+	AfxMessageBox(nlUtf8ToTStr(NLMISC::toString("%u ids checked, %u non unique ID regenerated", ids.size() + nonUnique.size(), nonUnique.size())), MB_OK);
 }
 
 // ***************************************************************************
@@ -4351,7 +4351,7 @@ void CMainFrame::OnMissionCompiler()
 	}
 	
 	TCHAR path[MAX_PATH];
-	_tcscpy(path, utf8ToTStr(var->asString()));
+	_tcscpy(path, nlUtf8ToTStr(var->asString()));
 
 	SHELLEXECUTEINFO ExecuteInfo;    
 	memset(&ExecuteInfo, 0, sizeof(ExecuteInfo));
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/my_list_box.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/my_list_box.cpp
index a071a4836..3546205c4 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/my_list_box.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/my_list_box.cpp
@@ -69,7 +69,7 @@ BOOL CMyListBox::OnCommand(WPARAM wParam, LPARAM lParam)
 				std::string str;
 				getWindowTextUTF8 (StringSelectComboBox, str);
 				DeleteString(_EditingItem);
-				InsertString(_EditingItem, utf8ToTStr(str));
+			    InsertString(_EditingItem, nlUtf8ToTStr(str));
 				SetCurSel (_SelectAfter);
 				_EditingItem = LB_ERR;
 				notifyParent ();
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/name_dlg.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/name_dlg.cpp
index bfa978ee4..1f3f68087 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/name_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/name_dlg.cpp
@@ -88,7 +88,7 @@ BOOL CNameDlg::OnInitDialog()
 
 	// print the data directory
 	CWnd* pWnd = GetDlgItem(IDC_NAME_DIR);
-	pWnd->SetWindowText(CString(_T("Data directory: ")) + utf8ToTStr(m_dataDir));
+	pWnd->SetWindowText(CString(_T("Data directory: ")) + nlUtf8ToTStr(m_dataDir));
 
 	// tab stops to simulate multi-columns edit boxes
 	int tab_stop1[1] = {160};
@@ -156,18 +156,18 @@ void CNameDlg::updateSearchList()
 		{
 			// no filter
 			m_listToName.insert(std::make_pair(j, i));
-			m_searchList.InsertString(j++, utf8ToTStr(s));
+			m_searchList.InsertString(j++, nlUtf8ToTStr(s));
 		}
 		else
 		{
-			std::string filter(tStrToUtf8(m_nameFilter.LockBuffer()));
+			std::string filter(NLMISC::tStrToUtf8(m_nameFilter.LockBuffer()));
 			m_nameFilter.UnlockBuffer();
 
 			// filter
 			if (NLMISC::toLower(ig).find(NLMISC::toLower(filter)) != std::string::npos)
 			{
 				m_listToName.insert(std::make_pair(j, i));
-				m_searchList.InsertString(j++, utf8ToTStr(s));
+				m_searchList.InsertString(j++, nlUtf8ToTStr(s));
 			}
 		}
 	}	
@@ -214,7 +214,7 @@ void CNameDlg::updateSelectList()
 			m_listToId.insert(std::make_pair(i, row));
 		}
 
-		m_idList.InsertString(i++, utf8ToTStr(s));
+		m_idList.InsertString(i++, nlUtf8ToTStr(s));
 	}
 }
 
@@ -251,8 +251,8 @@ void CNameDlg::OnBtnAssign()
 
 	// get strings
 	ucstring id;
-	std::string gn = tStrToUtf8(m_assignGn);
-	std::string ig = tStrToUtf8(m_assignIg);
+	std::string gn = NLMISC::tStrToUtf8(m_assignGn);
+	std::string ig = NLMISC::tStrToUtf8(m_assignIg);
 
 	for (uint i=0 ; i<sel.size() ; i++)
 	{
@@ -268,7 +268,7 @@ void CNameDlg::OnBtnAssign()
 			uint n = m_idList.GetTextLen(i);
 			m_idList.GetText(i, str.GetBuffer(n));
 			str.ReleaseBuffer();
-			id.fromUtf8(tStrToUtf8(str));
+			id.fromUtf8(NLMISC::tStrToUtf8(str));
 		}
 
 		// assign name to selected id
@@ -359,7 +359,7 @@ void CNameDlg::checkNewGn()
 {
 	// print a message if a new gn will be added to the list
 	CWnd* pWnd = GetDlgItem(IDC_NAME_NEWGN);
-	std::string s = tStrToUtf8(m_assignGn);
+	std::string s = NLMISC::tStrToUtf8(m_assignGn);
 	uint rowIndex;
 	if (s == "")
 	{
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/primitive_configuration_dlg.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/primitive_configuration_dlg.cpp
index 91346f6e7..f113a31b8 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/primitive_configuration_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/primitive_configuration_dlg.cpp
@@ -114,7 +114,7 @@ BOOL CPrimitiveConfigurationDlg::OnInitDialog()
 	uint i;
 	for (i=0; i<configurations.size(); i++)
 	{
-		ListCtrl.InsertItem (i, utf8ToTStr(configurations[i].Name));
+		ListCtrl.InsertItem(i, nlUtf8ToTStr(configurations[i].Name));
 		// setItemTextUTF8 (List, nItem, subString++, entry.Strings[CEntryFile::OldSize].c_str ());
 	}
 
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/project_settings.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/project_settings.cpp
index e2ada5702..700895992 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/project_settings.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/project_settings.cpp
@@ -75,9 +75,9 @@ void CProjectSettings::OnBrowse()
 {
 	UpdateData ();
 
-	BROWSEINFO	bi;
-	TCHAR		str[MAX_PATH];
-	ITEMIDLIST*	pidl;
+	BROWSEINFO	 bi;
+	TCHAR		 str[MAX_PATH];
+	LPITEMIDLIST pidl;
 	TCHAR sTemp[1024];
 
 	bi.hwndOwner = this->m_hWnd;
@@ -133,11 +133,11 @@ BOOL CProjectSettings::OnInitDialog()
 	for (uint i=0; i<contexts.size (); i++)
 	{
 		// Add the string
-		Context.InsertString (-1, utf8ToTStr(contexts[i]));
+		Context.InsertString(-1, nlUtf8ToTStr(contexts[i]));
 	}
 
 	// Select the string 
-	Context.SelectString (-1, utf8ToTStr(doc->getContext ()));
+	Context.SelectString(-1, nlUtf8ToTStr(doc->getContext()));
 
 	return TRUE;  // return TRUE unless you set the focus to a control
 	              // EXCEPTION: OCX Property Pages should return FALSE
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_logic.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_logic.cpp
index 7a5c25553..d8967a609 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_logic.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_logic.cpp
@@ -1231,7 +1231,7 @@ BOOL CCreateDialog::OnInitDialog ()
 
 	for (uint32 i = 0; i < TypesForInit->size(); ++i)
 	{
-		ComboType.InsertString (-1, utf8ToTStr(TypesForInit->operator[](i).Name));
+		ComboType.InsertString(-1, nlUtf8ToTStr(TypesForInit->operator[](i).Name));
 	}
 
 	if (TypesForInit->size()>0)
@@ -1264,10 +1264,10 @@ void CCreateDialog::OnOK()
 	UpdateData ();
 
 	// If the "region_" do not exist add it
-	if (_tcsnccmp(utf8ToTStr(RegionPost), Name, strlen(RegionPost.c_str())) != 0)
+	if (_tcsnccmp(nlUtf8ToTStr(RegionPost), Name, strlen(RegionPost.c_str())) != 0)
 	{
 		TCHAR sTmp[128];
-		_tcscpy (sTmp, utf8ToTStr(RegionPost));
+		_tcscpy(sTmp, nlUtf8ToTStr(RegionPost));
 		_tcscat (sTmp, Name);
 		_tcscpy (Name, sTmp);
 		UpdateData (false);
@@ -1303,11 +1303,11 @@ void CCreateDialog::OnSelChange ()
 
 	if (PropType == tStrToUtf8(sTmp))
 	{
-		_tcscpy (Name, utf8ToTStr(PropName));
+		_tcscpy(Name, nlUtf8ToTStr(PropName));
 	}
 	else
 	{
-		_tcscpy(Name, utf8ToTStr(RegionPost));
+		_tcscpy(Name, nlUtf8ToTStr(RegionPost));
 		_tcscat (Name, (LPCTSTR)sTmp);
 		_tcscat (Name, _T("-"));
 	}
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_zone.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_zone.cpp
index 231e57d28..bcb46cd6c 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_zone.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/tools_zone.cpp
@@ -105,7 +105,7 @@ void CToolsZoneList::reset()
 void CToolsZoneList::addItem (const string &itemName)
 {
 	_ItemNames.push_back (itemName);
-	InsertString (-1, utf8ToTStr(itemName));
+	InsertString(-1, nlUtf8ToTStr(itemName));
 }
 
 // ---------------------------------------------------------------------------
@@ -259,15 +259,15 @@ CToolsZoneList *CToolsZone::getListCtrl()
 // ---------------------------------------------------------------------------
 void CToolsZone::addToAllCatTypeCB (const string &Name)
 {
-	CComboBox* pCB;
-	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE1);
-	pCB->AddString (utf8ToTStr(Name));
-	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE2);
-	pCB->AddString (utf8ToTStr(Name));
-	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE3);
-	pCB->AddString (utf8ToTStr(Name));
-	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE4);
-	pCB->AddString (utf8ToTStr(Name));
+	CComboBox *pCB;
+	pCB = (CComboBox *)GetDlgItem(IDC_CATTYPE1);
+	pCB->AddString(nlUtf8ToTStr(Name));
+	pCB = (CComboBox *)GetDlgItem(IDC_CATTYPE2);
+	pCB->AddString(nlUtf8ToTStr(Name));
+	pCB = (CComboBox *)GetDlgItem(IDC_CATTYPE3);
+	pCB->AddString(nlUtf8ToTStr(Name));
+	pCB = (CComboBox *)GetDlgItem(IDC_CATTYPE4);
+	pCB->AddString(nlUtf8ToTStr(Name));
 }
 
 // ---------------------------------------------------------------------------
@@ -285,26 +285,26 @@ void CToolsZone::init (CMainFrame *pMF)
 	// Select right category types
 	CComboBox* pCB;
 	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE1);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType1));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType1));
 	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE2);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType2));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType2));
 	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE3);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType3));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType3));
 	pCB = (CComboBox*)GetDlgItem (IDC_CATTYPE4);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType4));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterType4));
 
 	updateComboPairAndFilter (IDC_CATTYPE1, IDC_CATVALUE1, &_MainFrame->_ZoneBuilder->_FilterType1);
 	pCB = (CComboBox*)GetDlgItem (IDC_CATVALUE1);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue1));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue1));
 	updateComboPairAndFilter (IDC_CATTYPE2, IDC_CATVALUE2, &_MainFrame->_ZoneBuilder->_FilterType2);
 	pCB = (CComboBox*)GetDlgItem (IDC_CATVALUE2);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue2));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue2));
 	updateComboPairAndFilter (IDC_CATTYPE3, IDC_CATVALUE3, &_MainFrame->_ZoneBuilder->_FilterType3);
 	pCB = (CComboBox*)GetDlgItem (IDC_CATVALUE3);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue3));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue3));
 	updateComboPairAndFilter (IDC_CATTYPE4, IDC_CATVALUE4, &_MainFrame->_ZoneBuilder->_FilterType4);
 	pCB = (CComboBox*)GetDlgItem (IDC_CATVALUE4);
-	pCB->SelectString (-1, utf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue4));
+	pCB->SelectString(-1, nlUtf8ToTStr(_MainFrame->_ZoneBuilder->_FilterValue4));
 
 	// Select right operators
 	CButton *pButAnd, *pButOr;
@@ -436,7 +436,7 @@ void CToolsZone::updateComboPairAndFilter (int CatTypeId, int CatValueId, string
 	CComboBox *pCBType, *pCBValue;
 	pCBType = (CComboBox*)GetDlgItem (CatTypeId);
 	pCBType->GetLBText (pCBType->GetCurSel(), sTmp);
-	*pFilterType = tStrToUtf8(sTmp);
+	*pFilterType = NLMISC::tStrToUtf8(sTmp);
 	pCBValue = (CComboBox*)GetDlgItem (CatValueId);
 	pCBValue->ResetContent ();
 
@@ -446,7 +446,7 @@ void CToolsZone::updateComboPairAndFilter (int CatTypeId, int CatValueId, string
 	vector<string> allCategoryValues;
 	_MainFrame->_ZoneBuilder->getZoneBank().getCategoryValues (*pFilterType, allCategoryValues);
 	for(i = 0; i < allCategoryValues.size(); ++i)
-		pCBValue->AddString (utf8ToTStr(allCategoryValues[i]));
+		pCBValue->AddString(nlUtf8ToTStr(allCategoryValues[i]));
 	pCBValue->SetCurSel (0);
 }
 
@@ -488,7 +488,7 @@ void CToolsZone::OnSelectCatValue1()
 	TCHAR sTmp[256];
 	CComboBox *pCBValue = (CComboBox*)GetDlgItem (IDC_CATVALUE1);
 	pCBValue->GetLBText (pCBValue->GetCurSel(), sTmp);
-	_MainFrame->_ZoneBuilder->_FilterValue1 = tStrToUtf8(sTmp);
+	_MainFrame->_ZoneBuilder->_FilterValue1 = NLMISC::tStrToUtf8(sTmp);
 	_MainFrame->_ZoneBuilder->updateToolsZone ();
 }
 
@@ -498,7 +498,7 @@ void CToolsZone::OnSelectCatValue2()
 	TCHAR sTmp[256];
 	CComboBox *pCBValue = (CComboBox*)GetDlgItem (IDC_CATVALUE2);
 	pCBValue->GetLBText (pCBValue->GetCurSel(), sTmp);
-	_MainFrame->_ZoneBuilder->_FilterValue2 = tStrToUtf8(sTmp);
+	_MainFrame->_ZoneBuilder->_FilterValue2 = NLMISC::tStrToUtf8(sTmp);
 	_MainFrame->_ZoneBuilder->updateToolsZone ();
 }
 
@@ -508,7 +508,7 @@ void CToolsZone::OnSelectCatValue3()
 	TCHAR sTmp[256];
 	CComboBox *pCBValue = (CComboBox*)GetDlgItem (IDC_CATVALUE3);
 	pCBValue->GetLBText (pCBValue->GetCurSel(), sTmp);
-	_MainFrame->_ZoneBuilder->_FilterValue3 = tStrToUtf8(sTmp);
+	_MainFrame->_ZoneBuilder->_FilterValue3 = NLMISC::tStrToUtf8(sTmp);
 	_MainFrame->_ZoneBuilder->updateToolsZone ();
 }
 
@@ -518,7 +518,7 @@ void CToolsZone::OnSelectCatValue4()
 	TCHAR sTmp[256];
 	CComboBox *pCBValue = (CComboBox*)GetDlgItem (IDC_CATVALUE4);
 	pCBValue->GetLBText (pCBValue->GetCurSel(), sTmp);
-	_MainFrame->_ZoneBuilder->_FilterValue4 = tStrToUtf8(sTmp);
+	_MainFrame->_ZoneBuilder->_FilterValue4 = NLMISC::tStrToUtf8(sTmp);
 	_MainFrame->_ZoneBuilder->updateToolsZone ();
 }
 
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/type_manager_dlg.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/type_manager_dlg.cpp
index ed39bda8e..f66915c90 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/type_manager_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/type_manager_dlg.cpp
@@ -77,7 +77,7 @@ void CTypeManagerDlg::OnAddtype()
 	if (typeDlg.DoModal() == IDOK)
 	{
 		SType typeTmp;
-		typeTmp.Name = tStrToUtf8(typeDlg.EditName);
+		typeTmp.Name = NLMISC::tStrToUtf8(typeDlg.EditName);
 		typeTmp.Color = typeDlg.ButtonColorValue;
 		// Check if the name of the new type is the same as an existing one
 		bool bFound = false;
@@ -91,7 +91,7 @@ void CTypeManagerDlg::OnAddtype()
 		if (!bFound)
 		{
 			LocalTypes.push_back (typeTmp);
-			ListType.InsertString(-1, utf8ToTStr(typeTmp.Name));
+			ListType.InsertString(-1, nlUtf8ToTStr(typeTmp.Name));
 		}
 	}
 }
@@ -111,11 +111,11 @@ void CTypeManagerDlg::OnEdittype()
 	if (typeDlg.DoModal() == IDOK)
 	{
 		SType typeTmp;
-		typeTmp.Name = tStrToUtf8(typeDlg.EditName);
+		typeTmp.Name = NLMISC::tStrToUtf8(typeDlg.EditName);
 		typeTmp.Color = typeDlg.ButtonColorValue;
 		LocalTypes[cursel] = typeTmp;
 		ListType.DeleteString (ListType.GetCurSel());
-		ListType.InsertString (cursel, utf8ToTStr(typeTmp.Name));
+		ListType.InsertString(cursel, nlUtf8ToTStr(typeTmp.Name));
 	}
 }
 
@@ -138,7 +138,7 @@ BOOL CTypeManagerDlg::OnInitDialog()
 	// TODO: Add extra initialization here
 	for (uint32 i = 0; i < LocalTypes.size(); ++i)
 	{
-		ListType.InsertString(-1, utf8ToTStr(LocalTypes[i].Name));
+		ListType.InsertString(-1, nlUtf8ToTStr(LocalTypes[i].Name));
 	}
 	
 	return TRUE;  // return TRUE unless you set the focus to a control
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/type_sel_dlg.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/type_sel_dlg.cpp
index 347fc72ad..d79e2c110 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/type_sel_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/type_sel_dlg.cpp
@@ -60,7 +60,7 @@ void CTypeSelDlg::OnOK()
 
 	CString sTmp;
 	TypeList.GetText(TypeList.GetCurSel(), sTmp);
-	_TypeSelected = tStrToUtf8(sTmp);
+	_TypeSelected = NLMISC::tStrToUtf8(sTmp);
 
 	CDialog::OnOK();
 }
@@ -72,7 +72,7 @@ BOOL CTypeSelDlg::OnInitDialog()
 	// TODO: Add extra initialization here
 	for (uint32 i = 0; i < _TypesInit->size(); ++i)
 	{
-		TypeList.InsertString(-1, utf8ToTStr(_TypesInit->operator[](i).Name));
+		TypeList.InsertString(-1, nlUtf8ToTStr(_TypesInit->operator[](i).Name));
 	}
 	
 	return TRUE;  // return TRUE unless you set the focus to a control
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor.cpp
index 1b3f96d04..f6e1743af 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor.cpp
@@ -170,7 +170,7 @@ BOOL CWorldEditorApp::InitInstance()
 	}
 	catch (const Exception& e)
 	{
-		::MessageBox (NULL, utf8ToTStr(e.what()), _T("Warning"), MB_OK|MB_ICONEXCLAMATION);
+		::MessageBox(NULL, nlUtf8ToTStr(e.what()), _T("Warning"), MB_OK | MB_ICONEXCLAMATION);
 
 		// Can't found the module put some default values
 		Config.CellSize = 160.0f;
@@ -292,7 +292,7 @@ BOOL CWorldEditorApp::InitInstance()
 	{
 		IPluginCallback* test=Plugins[k];
 		string retest=test->getName();
-		menu->InsertMenu( k, MF_BYPOSITION | MF_POPUP, ID_WINDOWS_PLUGINS+1 + k, utf8ToTStr(retest) );
+		menu->InsertMenu(k, MF_BYPOSITION | MF_POPUP, ID_WINDOWS_PLUGINS + 1 + k, nlUtf8ToTStr(retest));
 		menu->CheckMenuItem(ID_WINDOWS_PLUGINS+1 +k, MF_CHECKED);				
 	}
 	
@@ -444,7 +444,7 @@ bool CWorldEditorApp::yesNoMessage (const char *format, ... )
 		strcpy(buffer, "Unknown error");
 	}
 
-	return MessageBox (m_pMainWnd?m_pMainWnd->m_hWnd:NULL, utf8ToTStr(buffer), _T("NeL World Editor"), MB_YESNO|MB_ICONQUESTION) == IDYES;
+	return MessageBox(m_pMainWnd ? m_pMainWnd->m_hWnd : NULL, nlUtf8ToTStr(buffer), _T("NeL World Editor"), MB_YESNO | MB_ICONQUESTION) == IDYES;
 }
 
 void CWorldEditorApp::errorMessage (const char *format, ... )
@@ -463,7 +463,7 @@ void CWorldEditorApp::errorMessage (const char *format, ... )
 		strcpy(buffer, "Unknown error");
 	}
 
-	MessageBox (m_pMainWnd?m_pMainWnd->m_hWnd:NULL, utf8ToTStr(buffer), _T("NeL World Editor"), MB_OK|MB_ICONEXCLAMATION);
+	MessageBox(m_pMainWnd ? m_pMainWnd->m_hWnd : NULL, nlUtf8ToTStr(buffer), _T("NeL World Editor"), MB_OK | MB_ICONEXCLAMATION);
 }
 
 void CWorldEditorApp::infoMessage (const char *format, ... )
@@ -482,7 +482,7 @@ void CWorldEditorApp::infoMessage (const char *format, ... )
 		strcpy(buffer, "Unknown error");
 	}
 
-	MessageBox (m_pMainWnd?m_pMainWnd->m_hWnd:NULL, utf8ToTStr(buffer), _T("NeL World Editor"), MB_OK|MB_ICONINFORMATION);
+	MessageBox(m_pMainWnd ? m_pMainWnd->m_hWnd : NULL, nlUtf8ToTStr(buffer), _T("NeL World Editor"), MB_OK | MB_ICONINFORMATION);
 }
 
 void CWorldEditorApp::syntaxError (const std::string &filename, xmlNodePtr xmlNode, const char *format, ...)
@@ -813,7 +813,7 @@ void setEditTextMultiLine (CListBox &listBox, const std::vector<std::string> &ve
 	listBox.ResetContent();
 	uint i;
 	for (i=0; i<vect.size (); i++)
-		nlverify (listBox.InsertString( -1, utf8ToTStr(vect[i])) !=  LB_ERR);
+		nlverify(listBox.InsertString(-1, nlUtf8ToTStr(vect[i])) != LB_ERR);
 }
 
 // ***************************************************************************
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor_doc.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor_doc.cpp
index 2f85d6c01..58f1cc351 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor_doc.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/world_editor_doc.cpp
@@ -830,7 +830,7 @@ void CWorldEditorDoc::updateModifiedState ()
 		if ( (title.size ()>=2) && (title[title.size()-1] == '*') && (title[title.size()-2] == ' ') )
 		{
 			title.resize (title.size () - 2);
-			SetTitle (utf8ToTStr(title));
+			SetTitle(nlUtf8ToTStr(title));
 		}
 	}
 }
@@ -1532,8 +1532,8 @@ const NLLIGO::IPrimitive *CWorldEditorDoc::createPrimitive (const CDatabaseLocat
 		if (primClass->Type == CPrimitiveClass::Bitmap)
 		{
 			// Create a dialog file
-			CFileDialogEx dialog (BASE_REGISTRY_KEY, _T("image"), TRUE, utf8ToTStr(primClass->FileExtension), NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
-				utf8ToTStr(toString("%s (*.%s)|*.%s|All Files (*.*)|*.*||", primClass->FileType.c_str(), primClass->FileExtension.c_str(), primClass->FileExtension.c_str())), getMainFrame ());
+			CFileDialogEx dialog(BASE_REGISTRY_KEY, _T("image"), TRUE, nlUtf8ToTStr(primClass->FileExtension), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+			    nlUtf8ToTStr(toString("%s (*.%s)|*.%s|All Files (*.*)|*.*||", primClass->FileType.c_str(), primClass->FileExtension.c_str(), primClass->FileExtension.c_str())), getMainFrame());
 			if (dialog.DoModal() == IDOK)
 			{
 				// Save filename

From 8d67e139719bedbf168d4968d73ad49070ed05c2 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 07:53:19 +0800
Subject: [PATCH 51/75] Cleaning up unicode conversion

---
 .../world_editor_graph_plugin/graph_plugin.cpp       | 12 ++++++------
 .../world_editor_shard_monitor_plugin/plugin.cpp     |  4 ++--
 .../world_editor_sound_plugin/DialogFlags.cpp        |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/graph_plugin.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/graph_plugin.cpp
index d42b14eb8..aacc4a253 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/graph_plugin.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_graph_plugin/graph_plugin.cpp
@@ -172,7 +172,7 @@ void CGraphPlugin::refreshPrimitives()
 			{
 				string msg("Can't write script file '");
 				msg += tmpPath+"/lang.dot'";
-				AfxMessageBox(utf8ToTStr(msg));
+				AfxMessageBox(nlUtf8ToTStr(msg));
 			}
 			else
 			{
@@ -207,11 +207,11 @@ void CGraphPlugin::refreshPrimitives()
 
 				err = toString("%s : %s", primName.c_str(), e.Why.c_str());
 			}
-			AfxMessageBox(utf8ToTStr(err));
+			AfxMessageBox(nlUtf8ToTStr(err));
 		}
 		catch (const exception &e) //catch a possible exception from getRootFileName
 		{
-			AfxMessageBox(utf8ToTStr(e.what()));
+			AfxMessageBox(nlUtf8ToTStr(e.what()));
 		}
 	}
 	else
@@ -254,7 +254,7 @@ void CGraphPlugin::refreshMachine()
 		{
 			string msg("Can't write script file '");
 			msg += tmpPath+"/lang.dot'";
-			AfxMessageBox(utf8ToTStr(msg));
+			AfxMessageBox(nlUtf8ToTStr(msg));
 		}
 		else
 		{
@@ -298,7 +298,7 @@ void CGraphPlugin::refreshMachine()
 			{
 				string msg("Can't write script file '");
 				msg += tmpPath+"/lang.dot'";
-				AfxMessageBox(utf8ToTStr(msg));
+				AfxMessageBox(nlUtf8ToTStr(msg));
 			}
 			else
 			{
@@ -940,7 +940,7 @@ void CGraphPlugin::doSelection(const string& primPath)
 		}
 		catch(const exception &e)
 		{
-			GraphDlg->MessageBox(utf8ToTStr(e.what()));
+			GraphDlg->MessageBox(nlUtf8ToTStr(e.what()));
 		}
 	}
 }
\ No newline at end of file
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/plugin.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/plugin.cpp
index 72453fa70..30922cf1f 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/plugin.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_shard_monitor_plugin/plugin.cpp
@@ -1189,7 +1189,7 @@ void CPlugin::updateConnectionState()
 				// Change the text
 				_DialogFlag->ConnectCtrl.SetWindowText (getStringRsc(IDS_DISCONNECT));
 				_DialogFlag->State = (LPCTSTR) (getStringRsc(IDS_CONNECTED_TO) + _SHost.c_str());
-				_DialogFlag->Sent = CString(utf8ToTStr(toString (_Client->getBytesSent ()))) + getStringRsc(IDS_BYTE_SENT);
+			    _DialogFlag->Sent = CString(nlUtf8ToTStr(toString(_Client->getBytesSent()))) + getStringRsc(IDS_BYTE_SENT);
 				//_DialogFlag->Received = (toString ((uint32)_Client->getBytesReceived ()) + " bytes received").c_str();
 				_DialogFlag->Received = (toString("%.1f", bandwidth/1024.0) + " kB/s").c_str();
 				_DialogFlag->DownloadValue = (toString("%.1f kB/s", _DialogFlag->Download/1024.0)).c_str();
@@ -1198,7 +1198,7 @@ void CPlugin::updateConnectionState()
 			break;
 			case WaitingServerParams:				
 				_DialogFlag->ConnectCtrl.SetWindowText (getStringRsc(IDS_CANCEL_CONNECT));
-				_DialogFlag->State = getStringRsc(IDS_WAITING_SERVER_PARAMS) + utf8ToTStr(_SHost);
+			    _DialogFlag->State = getStringRsc(IDS_WAITING_SERVER_PARAMS) + nlUtf8ToTStr(_SHost);
 			break;
 			case WaitingLoginConfirmation:
 			{
diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/DialogFlags.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/DialogFlags.cpp
index 55cbbd25c..bf0857c39 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/DialogFlags.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_sound_plugin/DialogFlags.cpp
@@ -118,7 +118,7 @@ void CDialogFlags::init(CSoundPlugin *plugin)
 	for (uint i =0; i<NLSOUND::UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS; ++i)
 	{
 		static_cast<CButton*>(GetDlgItem(BG_FLAG_ID[i]))->SetCheck(flags.Flags[i] ? 1 : 0);
-		GetDlgItem(BG_FLAG_ID[i])->SetWindowText(utf8ToTStr(_Mixer->getBackgroundFlagName(i)));
+		GetDlgItem(BG_FLAG_ID[i])->SetWindowText(nlUtf8ToTStr(_Mixer->getBackgroundFlagName(i)));
 	}
 
 
@@ -229,7 +229,7 @@ void CDialogFlags::OnTimer(UINT_PTR nIDEvent)
 		_stprintf(temp, _T("%6.2f"), SampleBanks[i].second / (1024.0f*1024.0f));
 
 		TCHAR bankName[1024];
-		_tcscpy_s(bankName, 1024, utf8ToTStr(SampleBanks[i].first));
+		_tcscpy_s(bankName, 1024, nlUtf8ToTStr(SampleBanks[i].first));
 
 		if (i < c)
 		{

From aa489932d4a9686c1c8aaf83b77e4e764c1bbf07 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 07:55:11 +0800
Subject: [PATCH 52/75] Cleanup

---
 code/nel/include/nel/misc/common.h | 27 ++++-----------------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index c385af463..a4d6cb549 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -303,42 +303,23 @@ inline sint nlstricmp(const std::string &lhs, const std::string &rhs) { return s
 inline sint nlstricmp(const std::string &lhs, const char *rhs) { return stricmp(lhs.c_str(),rhs); }
 inline sint nlstricmp(const char *lhs, const std::string &rhs) { return stricmp(lhs,rhs.c_str()); }
 
-// TODO: Can we prefix these with 'nl' like other macros?
-// Macros helper to convert UTF-8 std::string and wchar_t*
-// #define wideToUtf8(str) (ucstring((ucchar*)str).toUtf8())
-// #define utf8ToWide(str) ((wchar_t*)ucstring::makeFromUtf8(str).c_str())
-
-// Macros helper to convert UTF-8 std::string and TCHAR*
-#ifdef _UNICODE
-// #define tStrToUtf8(str) (ucstring((ucchar*)(LPCWSTR)str).toUtf8())
-// #define utf8ToTStr(str) ((const wchar_t *)ucstring::makeFromUtf8(str).c_str())
-// #define tstring wstring
-#else
-// FIXME: This is not accurate, it should be a conversion between local charset and utf8
-// #define tStrToUtf8(str) (std::string((LPCSTR)str))
-// inline const char *nlutf8ToTStr(const char *str) { return str; }
-// inline const char *nlutf8ToTStr(const std::string &str) { return str.c_str(); }
-// #define utf8ToTStr(str) NLMISC::nlutf8ToTStr(str)
-// #define tstring string
-#endif
-
 #if (NL_COMP_VC_VERSION <= 90)
 inline float nlroundf(float x)
 {
-   return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
+	return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
 }
 #define roundf(x) NLMISC::nlroundf(x)
 #endif
 
 // Wrapper for fopen to be able to open files with an UTF-8 filename
-FILE* nlfopen(const std::string &filename, const std::string &mode);
+FILE *nlfopen(const std::string &filename, const std::string &mode);
 
 /** Signed 64 bit fseek. Same interface as fseek
   */
-int		nlfseek64( FILE *stream, sint64 offset, int origin );
+int nlfseek64(FILE *stream, sint64 offset, int origin);
 
 // Retrieve position in a file, same interface as ftell
-sint64  nlftell64(FILE *stream);
+sint64 nlftell64(FILE *stream);
 
 /**
  * Base class for all NeL exception.

From dc84e1fd2c7b001b23576b8a536019ce27fcc6d0 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 08:02:08 +0800
Subject: [PATCH 53/75] Fixed: World editor primitive plugin doesn't have a pch

---
 .../world_editor_primitive_plugin/CMakeLists.txt            | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/CMakeLists.txt b/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/CMakeLists.txt
index 56a7c1597..da490aa57 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/CMakeLists.txt
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor_primitive_plugin/CMakeLists.txt
@@ -14,9 +14,9 @@ NL_ADD_LIB_SUFFIX(world_editor_primitive_plugin)
 
 ADD_DEFINITIONS(${MFC_DEFINITIONS} -DWIN32_DLL_EXPORTS)
 
-IF(WITH_PCH)
-  ADD_NATIVE_PRECOMPILED_HEADER(world_editor_primitive_plugin ${CMAKE_CURRENT_SOURCE_DIR}/StdAfx.h ${CMAKE_CURRENT_SOURCE_DIR}/StdAfx.cpp)
-ENDIF()
+#IF(WITH_PCH)
+#  ADD_NATIVE_PRECOMPILED_HEADER(world_editor_primitive_plugin ${CMAKE_CURRENT_SOURCE_DIR}/StdAfx.h ${CMAKE_CURRENT_SOURCE_DIR}/StdAfx.cpp)
+#ENDIF()
 
 INSTALL(TARGETS world_editor_primitive_plugin LIBRARY DESTINATION ${RYZOM_LIB_PREFIX} RUNTIME DESTINATION ${RYZOM_BIN_PREFIX} ARCHIVE DESTINATION ${RYZOM_LIB_PREFIX} COMPONENT tools3d)
 

From af029b056c0b1c953223376597f29f8692e7e611 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 08:03:05 +0800
Subject: [PATCH 54/75] Fix LPITEMIDLIST type

---
 .../leveldesign/world_editor/world_editor/export_dlg.cpp    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/code/ryzom/tools/leveldesign/world_editor/world_editor/export_dlg.cpp b/code/ryzom/tools/leveldesign/world_editor/world_editor/export_dlg.cpp
index 7f290b784..cb58b0677 100644
--- a/code/ryzom/tools/leveldesign/world_editor/world_editor/export_dlg.cpp
+++ b/code/ryzom/tools/leveldesign/world_editor/world_editor/export_dlg.cpp
@@ -162,9 +162,9 @@ int CALLBACK expBrowseCallbackProc (HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData)
 // \return true if not canceled
 bool CExportDlg::callChoosePathDlg(CString &dest) const
 {
-	BROWSEINFO	bi;
-	TCHAR		str[MAX_PATH];
-	ITEMIDLIST*	pidl;
+	BROWSEINFO bi;
+	TCHAR str[MAX_PATH];
+	LPITEMIDLIST pidl;
 	TCHAR sTemp[1024];
 
 	bi.hwndOwner = this->m_hWnd;

From 9360c7974bd327449fdee64cc358f7b2684f6956 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 08:07:16 +0800
Subject: [PATCH 55/75] Fix empty cpp warning

---
 code/nel/src/3d/vertex_buffer_heap.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/code/nel/src/3d/vertex_buffer_heap.cpp b/code/nel/src/3d/vertex_buffer_heap.cpp
index e33a6757c..ad46d33d8 100644
--- a/code/nel/src/3d/vertex_buffer_heap.cpp
+++ b/code/nel/src/3d/vertex_buffer_heap.cpp
@@ -25,6 +25,8 @@ using namespace NLMISC;
 #define new DEBUG_NEW
 #endif
 
+void vertex_buffer_heap_dummy_cpp() { }
+
 // This code is not used actually and doesn't compile
 // just preproc comment it
 #if 0

From 605fec7dc85405e256eedd15724628ff40088033 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 08:12:42 +0800
Subject: [PATCH 56/75] Fix typo

---
 code/nel/src/misc/string_common.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/code/nel/src/misc/string_common.cpp b/code/nel/src/misc/string_common.cpp
index 3c8913ce1..ba911c1bc 100644
--- a/code/nel/src/misc/string_common.cpp
+++ b/code/nel/src/misc/string_common.cpp
@@ -286,7 +286,7 @@ std::string wideToMbcs(const wchar_t *str, size_t len)
 #if defined(NL_OS_WINDOWS)
 	return winWideToCp(str, len, CP_ACP);
 #else
-	return wideToUTf8(str, len);
+	return wideToUtf8(str, len);
 #endif
 }
 
@@ -295,7 +295,7 @@ std::string wideToMbcs(const std::wstring &str)
 #if defined(NL_OS_WINDOWS)
 	return winWideToCp(str.c_str(), str.size(), CP_ACP);
 #else
-	return wideToUTf8(str);
+	return wideToUtf8(str);
 #endif
 }
 

From bffb067345684557f6ac610e1a3086e905887cdd Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 08:17:30 +0800
Subject: [PATCH 57/75] Cleaning up unicode conversion

---
 code/nel/src/gui/lua_ihm.cpp                              | 2 +-
 code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/code/nel/src/gui/lua_ihm.cpp b/code/nel/src/gui/lua_ihm.cpp
index 4a51d221f..b36b9cca8 100644
--- a/code/nel/src/gui/lua_ihm.cpp
+++ b/code/nel/src/gui/lua_ihm.cpp
@@ -115,7 +115,7 @@ namespace NLGUI
 		{
 		#if !FINAL_VERSION
 			#ifdef NL_OS_WINDOWS
-				ShellExecuteW(NULL, utf8ToWide(operation), utf8ToWide(fileName), utf8ToWide(parameters), NULL, SW_SHOWDEFAULT);
+				ShellExecuteW(NULL, nlUtf8ToWide(operation), nlUtf8ToWide(fileName), nlUtf8ToWide(parameters), NULL, SW_SHOWDEFAULT);
 			#endif
 		#endif
 		}
diff --git a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp
index b47b05e84..7ef95260d 100644
--- a/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp
+++ b/code/nel/tools/3d/plugin_max/nel_mesh_lib/export_misc.cpp
@@ -764,7 +764,7 @@ void CExportNel::outputErrorMessage(const std::string &message)
 {
 	if (_ErrorInDialog)
 	{
-		MessageBoxW(_Ip->GetMAXHWnd(), utf8ToWide(message), utf8ToWide(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
+		MessageBoxW(_Ip->GetMAXHWnd(), nlUtf8ToWide(message), nlUtf8ToWide(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
 	}
 	mprintf(_M("%s\n"), MaxTStrFromUtf8(message).data());
 
@@ -778,7 +778,7 @@ void CExportNel::outputWarningMessage(const std::string &message)
 {
 	if (_ErrorInDialog)
 	{
-		MessageBoxW(_Ip->GetMAXHWnd(), utf8ToWide(message), utf8ToWide(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
+		MessageBoxW(_Ip->GetMAXHWnd(), nlUtf8ToWide(message), nlUtf8ToWide(_ErrorTitle), MB_OK|MB_ICONEXCLAMATION);
 	}
 	mprintf(_M("%s\n"), MaxTStrFromUtf8(message).data());
 

From 44124e58539f587f4abcdee39c5434369019a951 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 09:27:50 +0800
Subject: [PATCH 58/75] Support MariaDB C connector library instead of MySQL

---
 code/CMakeModules/FindMySQL.cmake | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/code/CMakeModules/FindMySQL.cmake b/code/CMakeModules/FindMySQL.cmake
index 8a92cb0c4..631a96224 100644
--- a/code/CMakeModules/FindMySQL.cmake
+++ b/code/CMakeModules/FindMySQL.cmake
@@ -16,10 +16,12 @@ IF(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
 ELSE()
 
   FIND_PATH(MYSQL_INCLUDE_DIR mysql.h
-      PATH_SUFFIXES mysql
+      PATH_SUFFIXES mysql mariadb
       PATHS
       /usr/include/mysql
+      /usr/include/mariadb
       /usr/local/include/mysql
+      /usr/local/include/mariadb
       /opt/local/include/mysql5/mysql
       /opt/local/include/mysql55/mysql
       /opt/local/include/mysql51/mysql
@@ -27,28 +29,29 @@ ELSE()
       $ENV{SystemDrive}/MySQL/*/include)
 
   IF(WIN32 AND MSVC)
-    FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES libmysql mysqlclient
+    FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES libmysql mysqlclient libmariadb mariadbclient
       PATHS
       $ENV{ProgramFiles}/MySQL/*/lib/opt
       $ENV{SystemDrive}/MySQL/*/lib/opt)
-
-    FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES libmysqld mysqlclientd
+    FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES libmysqld mysqlclientd libmariadb mariadbclient
       PATHS
       $ENV{ProgramFiles}/MySQL/*/lib/opt
       $ENV{SystemDrive}/MySQL/*/lib/opt)
   ELSE()
-    FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient
+    FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient mariadbclient
       PATHS
       /usr/lib
       /usr/local/lib
+      /usr/lib/mariadb
       /usr/lib/mysql
       /usr/local/lib/mysql
+      /usr/local/lib/mariadb
       /opt/local/lib/mysql5/mysql
       /opt/local/lib/mysql55/mysql
       /opt/local/lib/mysql51/mysql
       )
 
-    FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES mysqlclientd
+    FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES mysqlclientd mariadbclientd
       PATHS
       /usr/lib
       /usr/local/lib
@@ -80,6 +83,10 @@ ELSE()
   IF(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
     SET(MYSQL_FOUND TRUE)
     MESSAGE(STATUS "Found MySQL: ${MYSQL_INCLUDE_DIR}, ${MYSQL_LIBRARIES}")
+    IF (MYSQL_LIBRARIES MATCHES "libmariadb" OR MYSQL_LIBRARIES MATCHES "mariadbclient")
+      SET(MARIADB_FOUND TRUE)
+      MESSAGE(STATUS "Found MariaDB.")
+    ENDIF()
   ELSE()
     SET(MYSQL_FOUND FALSE)
     MESSAGE(STATUS "MySQL not found.")

From 1c422390e76aee787feb62df939436ccdf5cbdd8 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 10:17:01 +0800
Subject: [PATCH 59/75] Cleaning up unicode conversion

---
 code/nel/include/nel/net/service.h                  | 10 ++++++++++
 code/nel/src/3d/driver/direct3d/driver_direct3d.cpp |  2 +-
 code/ryzom/client/src/login_xdelta.cpp              |  2 +-
 code/ryzom/client/src/permanent_ban.cpp             |  6 +++---
 4 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/code/nel/include/nel/net/service.h b/code/nel/include/nel/net/service.h
index bdabb48a1..8b79bdc55 100644
--- a/code/nel/include/nel/net/service.h
+++ b/code/nel/include/nel/net/service.h
@@ -54,7 +54,17 @@ struct HINSTANCE__;
 typedef struct HINSTANCE__ *HINSTANCE;
 
 typedef char CHAR;
+typedef wchar_t WCHAR;
+
 typedef CHAR *LPSTR;
+typedef WCHAR *LPWSTR;
+
+#if defined(UNICODE) || defined(_UNICODE)
+typedef LPWSTR LPTSTR;
+#else
+typedef LPSTR LPTSTR;
+#endif
+
 #endif
 
 namespace NLNET
diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp
index 7a4618683..43d33d081 100644
--- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp
+++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp
@@ -1810,7 +1810,7 @@ emptyProc CDriverD3D::getWindowProc()
 
 IDriver::TMessageBoxId CDriverD3D::systemMessageBox (const char* message, const char* title, TMessageBoxType type, TMessageBoxIcon icon)
 {
-	switch (::MessageBoxW (_HWnd, utf8ToWide(message), utf8ToWide(title), ((type==retryCancelType)?MB_RETRYCANCEL:
+	switch (::MessageBoxW(_HWnd, nlUtf8ToWide(message), nlUtf8ToWide(title), ((type == retryCancelType) ? MB_RETRYCANCEL :
 		(type==yesNoCancelType)?MB_YESNOCANCEL:
 		(type==okCancelType)?MB_OKCANCEL:
 		(type==abortRetryIgnoreType)?MB_ABORTRETRYIGNORE:
diff --git a/code/ryzom/client/src/login_xdelta.cpp b/code/ryzom/client/src/login_xdelta.cpp
index c70304dc2..8cb8beaa1 100644
--- a/code/ryzom/client/src/login_xdelta.cpp
+++ b/code/ryzom/client/src/login_xdelta.cpp
@@ -95,7 +95,7 @@ bool CXDPFileReader::init(const std::string &sFilename, sint32 nLowerBound, sint
 	{
 		// First open the file with a normal function
 #ifdef NL_OS_WINDOWS
-		int fd = _wopen(utf8ToWide(sFilename), _O_BINARY | _O_RDONLY);
+		int fd = _wopen(nlUtf8ToWide(sFilename), _O_BINARY | _O_RDONLY);
 #else
 		int fd = open(sFilename.c_str(), O_RDONLY);
 #endif
diff --git a/code/ryzom/client/src/permanent_ban.cpp b/code/ryzom/client/src/permanent_ban.cpp
index dab097c79..5c9cbbb1f 100644
--- a/code/ryzom/client/src/permanent_ban.cpp
+++ b/code/ryzom/client/src/permanent_ban.cpp
@@ -87,9 +87,9 @@ static void setPermanentBanFileMarker(const std::string &path, bool on)
 		{
 			// simply touch a file
 			COFile f(path);
-			#ifdef NL_OS_WINDOWS
-				SetFileAttributesW(utf8ToWide(path), FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
-			#endif
+#ifdef NL_OS_WINDOWS
+			SetFileAttributesW(nlUtf8ToWide(path), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
+#endif
 		}
 		catch(const EStream &e)
 		{

From a249fcbab34e691cfc137339596657dabf939f62 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 10:17:44 +0800
Subject: [PATCH 60/75] Support build with OpenAL-Soft on Windows

---
 code/nel/src/sound/driver/openal/CMakeLists.txt |  7 +++++--
 code/nel/src/sound/driver/openal/ext_al.h       | 12 ++++++------
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/code/nel/src/sound/driver/openal/CMakeLists.txt b/code/nel/src/sound/driver/openal/CMakeLists.txt
index 911214a57..22b3f4348 100644
--- a/code/nel/src/sound/driver/openal/CMakeLists.txt
+++ b/code/nel/src/sound/driver/openal/CMakeLists.txt
@@ -36,8 +36,11 @@ NL_ADD_LIB_SUFFIX(${NLDRV_AL_LIB})
 IF(WIN32)
   # Find and include EFX-Util on Windows.
   FIND_PACKAGE(EFXUtil)
-  INCLUDE_DIRECTORIES(${EFXUTIL_INCLUDE_DIR})
-  TARGET_LINK_LIBRARIES(${NLDRV_AL_LIB} ${EFXUTIL_LIBRARY})
+  IF(EFXUTIL_FOUND)
+    INCLUDE_DIRECTORIES(${EFXUTIL_INCLUDE_DIR})
+    TARGET_LINK_LIBRARIES(${NLDRV_AL_LIB} ${EFXUTIL_LIBRARY})
+    ADD_DEFINITIONS(-DEFX_CREATIVE_AVAILABLE=1)
+  ENDIF()
 ENDIF()
 
 IF(WITH_PCH)
diff --git a/code/nel/src/sound/driver/openal/ext_al.h b/code/nel/src/sound/driver/openal/ext_al.h
index 0b7eaa2bf..b87cf48f2 100644
--- a/code/nel/src/sound/driver/openal/ext_al.h
+++ b/code/nel/src/sound/driver/openal/ext_al.h
@@ -17,12 +17,12 @@
 #ifndef NL_EXT_AL_H
 #define NL_EXT_AL_H
 
-#ifdef NL_OS_WINDOWS
-#	define EFX_CREATIVE_AVAILABLE 1
-#	define EAX_AVAILABLE 0
-#else
-#	define EFX_CREATIVE_AVAILABLE 0
-#	define EAX_AVAILABLE 0
+#ifndef EFX_CREATIVE_AVAILABLE
+#define EFX_CREATIVE_AVAILABLE 0
+#endif
+
+#ifndef EAX_AVAILABLE
+#define EAX_AVAILABLE 0
 #endif
 
 #if EAX_AVAILABLE

From aa8f17671af93bfc9f78cc57a956f5b94929e3f7 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 11:42:53 +0800
Subject: [PATCH 61/75] Cleaning up unicode conversion

---
 code/nel/include/nel/misc/string_common.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/code/nel/include/nel/misc/string_common.h b/code/nel/include/nel/misc/string_common.h
index d21b75d43..431b517d7 100644
--- a/code/nel/include/nel/misc/string_common.h
+++ b/code/nel/include/nel/misc/string_common.h
@@ -357,6 +357,9 @@ inline tstring mbcsToTStr(const std::string &str) { return (const tstring &)str;
 #define nlMbcsToTStr(str) ((const tchar *)NLMISC::asCStr(str))
 #endif
 
+inline const tchar* asCStr(const tchar *str) { return str; }
+inline const tchar* asCStr(const tstring &str) { return str.c_str(); }
+
 } // NLMISC
 
 #endif	// NL_STRING_COMMON_H

From b59efe8ff09961bcf2ebd35530947b049544ef78 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 11:45:44 +0800
Subject: [PATCH 62/75] Cleanup

---
 code/nel/include/nel/misc/string_common.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/code/nel/include/nel/misc/string_common.h b/code/nel/include/nel/misc/string_common.h
index 431b517d7..4ce793670 100644
--- a/code/nel/include/nel/misc/string_common.h
+++ b/code/nel/include/nel/misc/string_common.h
@@ -285,10 +285,10 @@ std::string wideToMbcs(const std::wstring &str);
 std::wstring mbcsToWide(const char *str, size_t len = 0);
 std::wstring mbcsToWide(const std::string &str);
 
-inline const char* asCStr(const char *str) { return str; }
-inline const char* asCStr(const std::string &str) { return str.c_str(); }
-inline const wchar_t* asCStr(const wchar_t *str) { return str; }
-inline const wchar_t* asCStr(const std::wstring &str) { return str.c_str(); }
+inline const char *asCStr(const char *str) { return str; }
+inline const char *asCStr(const std::string &str) { return str.c_str(); }
+inline const wchar_t *asCStr(const wchar_t *str) { return str; }
+inline const wchar_t *asCStr(const std::wstring &str) { return str.c_str(); }
 
 #if defined(NL_OS_WINDOWS)
 #define nlUtf8ToMbcs(str) (NLMISC::utf8ToMbcs(str).c_str())
@@ -357,8 +357,8 @@ inline tstring mbcsToTStr(const std::string &str) { return (const tstring &)str;
 #define nlMbcsToTStr(str) ((const tchar *)NLMISC::asCStr(str))
 #endif
 
-inline const tchar* asCStr(const tchar *str) { return str; }
-inline const tchar* asCStr(const tstring &str) { return str.c_str(); }
+inline const tchar *asCStr(const tchar *str) { return str; }
+inline const tchar *asCStr(const tstring &str) { return str.c_str(); }
 
 } // NLMISC
 

From 83fdb7b4a10026e53d1f4fc0428caeac2809effc Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 11:52:03 +0800
Subject: [PATCH 63/75] Cleaning up unicode conversion

---
 code/nel/include/nel/misc/string_common.h | 3 ---
 code/nel/include/nel/net/service.h        | 5 ++++-
 code/nel/src/net/service.cpp              | 7 +++++++
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/code/nel/include/nel/misc/string_common.h b/code/nel/include/nel/misc/string_common.h
index 4ce793670..bb972a4eb 100644
--- a/code/nel/include/nel/misc/string_common.h
+++ b/code/nel/include/nel/misc/string_common.h
@@ -357,9 +357,6 @@ inline tstring mbcsToTStr(const std::string &str) { return (const tstring &)str;
 #define nlMbcsToTStr(str) ((const tchar *)NLMISC::asCStr(str))
 #endif
 
-inline const tchar *asCStr(const tchar *str) { return str; }
-inline const tchar *asCStr(const tstring &str) { return str.c_str(); }
-
 } // NLMISC
 
 #endif	// NL_STRING_COMMON_H
diff --git a/code/nel/include/nel/net/service.h b/code/nel/include/nel/net/service.h
index 8b79bdc55..5d99477ff 100644
--- a/code/nel/include/nel/net/service.h
+++ b/code/nel/include/nel/net/service.h
@@ -146,7 +146,7 @@ int nltmain(int argc, const NLMISC::tchar **argv) \
 { \
 	NLMISC::CApplicationContext serviceContext; \
 	__ServiceClassName *scn = new __ServiceClassName; \
-	scn->setArgs (argc, nlTStrToUtf8(argv)); \
+	scn->setArgs (argc, argv); \
 	createDebug(NULL,!scn->haveLongArg("nolog"));\
 	scn->setCallbackArray (__ServiceCallbackArray, sizeof(__ServiceCallbackArray)/sizeof(__ServiceCallbackArray[0])); \
 	sint retval = scn->main (__ServiceShortName, __ServiceLongName, __ServicePort, __ConfigDir, __LogDir, __DATE__ " " __TIME__); \
@@ -350,6 +350,9 @@ public:
 	/// Sets the command line and init _Args variable. You must call this before calling main()
 	void setArgs (int argc, const char **argv);
 
+	/// Sets the command line and init _Args variable. You must call this before calling main()
+	void setArgs (int argc, const wchar_t **argv);
+
 	/// Sets the command line and init _Args variable. You must call this before calling main()
 	void setArgs (const char *args);
 
diff --git a/code/nel/src/net/service.cpp b/code/nel/src/net/service.cpp
index 24064db55..b0242bb86 100644
--- a/code/nel/src/net/service.cpp
+++ b/code/nel/src/net/service.cpp
@@ -492,6 +492,13 @@ void IService::setArgs (int argc, const char **argv)
 	}
 }
 
+void IService::setArgs(int argc, const wchar_t **argv)
+{
+	for (sint i = 0; i < argc; i++)
+	{
+		_Args.push_back(nlWideToUtf8(argv[i]));
+	}
+}
 
 void cbLogFilter (CConfigFile::CVar &var)
 {

From d1fd45b29a8ad6f8ad1f574cedcd917bae0e3c82 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 12:49:01 +0800
Subject: [PATCH 64/75] Adjust test case

---
 .../tools/nel_unit_test/ut_misc_string_common.h   | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/code/nel/tools/nel_unit_test/ut_misc_string_common.h b/code/nel/tools/nel_unit_test/ut_misc_string_common.h
index 623d2d39e..b7c133e17 100644
--- a/code/nel/tools/nel_unit_test/ut_misc_string_common.h
+++ b/code/nel/tools/nel_unit_test/ut_misc_string_common.h
@@ -707,6 +707,12 @@ struct CUTMiscStringCommon : public Test::Suite
 		ret = NLMISC::fromString("yes", val);
 		TEST_ASSERT(ret && val);
 
+		ret = NLMISC::fromString("YES", val);
+		TEST_ASSERT(ret && val);
+
+		ret = NLMISC::fromString("True", val);
+		TEST_ASSERT(ret && val);
+
 		// false values
 		ret = NLMISC::fromString("0", val);
 		TEST_ASSERT(ret && !val);
@@ -730,14 +736,17 @@ struct CUTMiscStringCommon : public Test::Suite
 		TEST_ASSERT(ret && !val);
 
 		// wrong values
-		ret = NLMISC::fromString("YES", val);
-		TEST_ASSERT(!ret && !val);
-
 		ret = NLMISC::fromString("foo", val);
 		TEST_ASSERT(!ret && !val);
 
 		ret = NLMISC::fromString("a", val);
 		TEST_ASSERT(!ret && !val);
+
+		ret = NLMISC::fromString("Yesss", val);
+		TEST_ASSERT(!ret && !val);
+
+		ret = NLMISC::fromString("nope", val);
+		TEST_ASSERT(!ret && !val);
 	}
 };
 

From eafe83cbe287224e944fca0976973a09de117a24 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 14:04:57 +0800
Subject: [PATCH 65/75] Add option for custom compile flags

---
 code/CMakeModules/nel.cmake | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake
index b216eb1e4..bd70dd2ff 100644
--- a/code/CMakeModules/nel.cmake
+++ b/code/CMakeModules/nel.cmake
@@ -568,6 +568,11 @@ MACRO(NL_SETUP_BUILD)
     ADD_PLATFORM_FLAGS("-DENABLE_LOGS")
   ENDIF()
 
+  SET(CUSTOM_FLAGS "" CACHE STRING "Custom compile flags (useful for /MPn)")
+  IF(NOT ${CUSTOM_FLAGS} STREQUAL "")
+    ADD_PLATFORM_FLAGS(${CUSTOM_FLAGS})
+  ENDIF()
+
   IF(MSVC)
     # Ignore default include paths
     ADD_PLATFORM_FLAGS("/X")

From b04cab3ec0ad5f89cd2fbe6c6374c5c680405316 Mon Sep 17 00:00:00 2001
From: kaetemi <kaetemi@gmail.com>
Date: Wed, 1 May 2019 16:11:48 +0800
Subject: [PATCH 66/75] Enable music in snowballs

---
 code/snowballs2/bin/snowballs_client.cfg      |   6 +-
 .../bin/snowballs_client_default.cfg          |   3 +-
 code/snowballs2/client/src/CMakeLists.txt     |   4 +-
 code/snowballs2/client/src/entities.cpp       |   4 +-
 .../client/src/snowballs_client.cpp           |  56 +--
 code/snowballs2/client/src/snowballs_config.h |   4 +-
 code/snowballs2/client/src/sound.cpp          | 360 ++++++++++--------
 code/snowballs2/client/src/sound.h            |  36 +-
 8 files changed, 252 insertions(+), 221 deletions(-)

diff --git a/code/snowballs2/bin/snowballs_client.cfg b/code/snowballs2/bin/snowballs_client.cfg
index 9cc10b7ad..b2432c733 100644
--- a/code/snowballs2/bin/snowballs_client.cfg
+++ b/code/snowballs2/bin/snowballs_client.cfg
@@ -7,10 +7,12 @@ Password             = "password2";
 LSHost               = "opennel.org:49994";
 FSHost               = "";
 SaveConfig           = 1;
-SoundEnabled         = 0;
-SoundDriver          = "FMod";
+SoundEnabled         = 1;
+SoundDriver          = "OpenAl";
+MusicVolume          = 0.2;
 ScreenWidth          = 1024;
 ScreenHeight         = 768;
+ScreenFull           = 0;
 ShardId              = 300;
 UseDirectClient      = 1;
 ClientApplication    = "snowballs";
diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg
index f8af00386..af099a449 100755
--- a/code/snowballs2/bin/snowballs_client_default.cfg
+++ b/code/snowballs2/bin/snowballs_client_default.cfg
@@ -75,12 +75,13 @@ HMDDevice = "Auto";
 //////////////////////////////////////////////////////////////////////////////
 
 // The sound driver, choose between "Auto", "FMod", "DSound" and "OpenAl"
-SoundDriver          = "FMod";
+SoundDriver          = "OpenAl";
 SoundMaxTracks       = 32;
 SoundUseEax          = 1;
 SoundUseADPCM        = 1;
 SoundForceSoftware   = 1;
 SoundEnabled         = 1;
+MusicVolume          = 0.2;
 
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/code/snowballs2/client/src/CMakeLists.txt b/code/snowballs2/client/src/CMakeLists.txt
index 8125eb3c2..18a2c126c 100644
--- a/code/snowballs2/client/src/CMakeLists.txt
+++ b/code/snowballs2/client/src/CMakeLists.txt
@@ -12,9 +12,9 @@ NL_DEFAULT_PROPS(snowballs_client "Snowballs, Client: Snowballs Client")
 NL_ADD_RUNTIME_FLAGS(snowballs_client)
 
 # If sound is enabled then add the definitions and link the libraries.
-IF(ENABLE_SOUND)
+IF(WITH_SOUND)
   ADD_DEFINITIONS(-DSBCLIENT_WITH_SOUND)
-  TARGET_LINK_LIBRARIES(snowballs_client ${NELSOUND_LIBRARY})
+  TARGET_LINK_LIBRARIES(snowballs_client nelsound)
 ENDIF()
 
 INSTALL(TARGETS snowballs_client RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT snowballsclient)
diff --git a/code/snowballs2/client/src/entities.cpp b/code/snowballs2/client/src/entities.cpp
index 2972aebf1..dde6df257 100644
--- a/code/snowballs2/client/src/entities.cpp
+++ b/code/snowballs2/client/src/entities.cpp
@@ -762,10 +762,10 @@ void updateEntities ()
 			switch (entity.Type)
 			{
 			case CEntity::Self:
-				jdir = CVector(-(float)cos(entity.Angle), -(float)sin(entity.Angle), 0.0f);
+				jdir = CVector(-(float)cos(entity.Angle - (Pi * 0.5)), -(float)sin(entity.Angle - (Pi * 0.5)), 0.0f);
 				break;
 			case CEntity::Other:
-				jdir = CVector(-(float)cos(entity.Angle), -(float)sin(entity.Angle), 0.0f);
+				jdir = CVector(-(float)cos(entity.Angle - (Pi * 0.5)), -(float)sin(entity.Angle - (Pi * 0.5)), 0.0f);
 				break;
 			case CEntity::Snowball:
 				jdir = entity.Trajectory.evalSpeed(LocalTime).normed();
diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp
index 059960922..28f957589 100644
--- a/code/snowballs2/client/src/snowballs_client.cpp
+++ b/code/snowballs2/client/src/snowballs_client.cpp
@@ -68,6 +68,7 @@
 #include "interface.h"
 #include "lens_flare.h"
 #include "mouse_listener.h"
+#include "sound.h"
 #include "configuration.h"
 #include "internationalization.h"
 #include "game_time.h"
@@ -301,6 +302,8 @@ void initCore()
 		LoadedCore = true;
 		// Seed the randomizer
 		srand(uint(time(0)));
+		// Sheet Id
+		CSheetId::initWithoutSheet(); // Temporary for sound
 		// Load configuration file, set paths, extension remapping
 		CConfiguration::init();
 		// Load language file
@@ -333,11 +336,9 @@ void initCore()
 		displayLoadingState("Initialize Loading");
 		initLoadingState();
 		// Initialize sound for loading screens etc
-//#ifdef NL_OS_WINDOWS
-//		displayLoadingState("Initialize Sound");
-//		initSound();
-//		playMusic(SBCLIENT_MUSIC_WAIT);
-//#endif
+		displayLoadingState("Initialize Sound");
+		initSound();
+		playMusic(SBCLIENT_MUSIC_WAIT);
 		// Required for 3d rendering (3d nel logo etc)
 		displayLoadingState("Initialize Light");
 		initLight();
@@ -366,9 +367,7 @@ void initIngame()
 	if (!LoadedIngame)
 	{
 		LoadedIngame = true;
-//#ifdef NL_OS_WINDOWS
-//		playMusic(SBCLIENT_MUSIC_WAIT);
-//#endif
+		playMusic(SBCLIENT_MUSIC_WAIT);
 		displayLoadingState("Initialize");
 
 		// Create a scene
@@ -441,10 +440,9 @@ void initIngame()
 
 void initOnline()
 {
-	if (LoadedOnline) return;
-//#ifdef NL_OS_WINDOWS
-//	playMusic(SBCLIENT_MUSIC_WAIT);
-//#endif
+	if (LoadedOnline)
+		return;
+	playMusic(SBCLIENT_MUSIC_WAIT);
 
 	displayLoadingState("Connecting");
 
@@ -460,9 +458,7 @@ void initOnline()
 
 	displayLoadingState("Ready!");
 
-//#ifdef NL_OS_WINDOWS
-//	playMusic(SBCLIENT_MUSIC_BACKGROUND);
-//#endif
+	playMusic(SBCLIENT_MUSIC_BACKGROUND);
 	LoadedOnline = true;
 }
 
@@ -471,9 +467,7 @@ void initOffline()
 	if (!LoadedOffline)
 	{
 		LoadedOffline = true;
-//#ifdef NL_OS_WINDOWS
-//		playMusic(SBCLIENT_MUSIC_WAIT);
-//#endif
+		playMusic(SBCLIENT_MUSIC_WAIT);
 
 		uint32 id = NextEID++;
 		Login = ucstring("Entity" + toString(id));
@@ -492,9 +486,7 @@ void initOffline()
 
 		displayLoadingState("Ready!");
 
-//#ifdef NL_OS_WINDOWS
-//		playMusic(SBCLIENT_MUSIC_BACKGROUND);
-//#endif
+		playMusic(SBCLIENT_MUSIC_BACKGROUND);
 	}
 }
 
@@ -517,9 +509,7 @@ void releaseCore()
 		// Release the loading state textures
 		releaseLoadingState();
 		// Release the sound
-//#ifdef NL_OS_WINDOWS
-//		releaseSound();
-//#endif
+		releaseSound();
 		// Release the text context
 		Driver->deleteTextContext(TextContext);
 		TextContext = NULL;
@@ -529,11 +519,13 @@ void releaseCore()
 		Driver = NULL;
 
 		// Release timing system
-		CGameTime::init();
+		CGameTime::release();
 		// Release language file
-		CInternationalization::init();
+		CInternationalization::release();
 		// Release the configuration
 		CConfiguration::release();
+		// Release sheet id
+		CSheetId::uninit(); // Temporary for sound
 	}
 }
 
@@ -611,9 +603,7 @@ void releaseOffline()
 
 void loopLogin()
 {
-//#ifdef NL_OS_WINDOWS
-//	playMusic(SBCLIENT_MUSIC_LOGIN);
-//#endif
+	playMusic(SBCLIENT_MUSIC_LOGIN);
 	// todo: login screen, move this stuff to a button or something
 	displayLoadingState("Login");
 	if (ConfigFile->getVar("Local").asInt() == 0)
@@ -730,9 +720,7 @@ void loopIngame()
 		// ...
 
 		// 11. Update Sound (sound driver)
-//#ifdef NL_OS_WINDOWS
-//		updateSound(); // Update the sound
-//#endif
+		updateSound(); // Update the sound
 
 		// 12. Update Outgoing (network, send new position etc)
 		// ...
@@ -1118,9 +1106,7 @@ void updateLoadingState(const char *state, bool network, bool information)
 void updateLoadingState(ucstring state, bool network, bool information)
 {
 	CGameTime::updateTime(); // important that time is updated here!!!
-//#ifdef NL_OS_WINDOWS
-//	updateSound();
-//#endif
+	updateSound();
 	renderLoadingState(state, true);
 	if (information) renderInformation();
 	if (network) updateNetwork();
diff --git a/code/snowballs2/client/src/snowballs_config.h b/code/snowballs2/client/src/snowballs_config.h
index 2e6b848fb..ee216f3c5 100644
--- a/code/snowballs2/client/src/snowballs_config.h
+++ b/code/snowballs2/client/src/snowballs_config.h
@@ -41,7 +41,9 @@
 // - Bloom
 // 2.2
 // - OculusVR support
-#define SBCLIENT_VERSION "2.2"
+// 2.3
+// - Add music
+#define SBCLIENT_VERSION "2.3"
 
 
 
diff --git a/code/snowballs2/client/src/sound.cpp b/code/snowballs2/client/src/sound.cpp
index 7ad802e03..f0a767825 100644
--- a/code/snowballs2/client/src/sound.cpp
+++ b/code/snowballs2/client/src/sound.cpp
@@ -30,8 +30,10 @@
 #include <nel/sound/u_listener.h>
 #include <nel/sound/u_source.h>
 
+#include "snowballs_client.h"
 #include "sound.h"
 #include "entities.h"
+#include "configuration.h"
 
 //
 // Namespaces
@@ -41,116 +43,149 @@ using namespace std;
 using namespace NLMISC;
 using namespace NLSOUND;
 
-#ifdef SBCLIENT_WITH_SOUND
+namespace SBCLIENT
+{
 
-////
-//// Variables
-////
 //
-//UAudioMixer *AudioMixer = NULL;
+// Variables
+///
+
+#ifdef SBCLIENT_WITH_SOUND
+UAudioMixer *AudioMixer = NULL;
 //TSoundId SoundId;
 //const vector<TSoundId> *SoundIdArray;
-//static bool SoundEnabled;
+static bool SoundEnabled;
+#endif
+
 //
-////
-//// Functions
-////
-//
-//#ifdef NL_OS_WINDOWS
-//void initSound2();
-//void releaseSound2();
-//#endif
-//
-//void cbConfigFileSoundMaxTracks(NLMISC::CConfigFile::CVar &var)
-//{
-////#ifdef NL_OS_WINDOWS
-////	AudioMixer->changeMaxTrack(var.asInt());
-////#endif
-//}
-//
-//void cbConfigFileSoundEnabled(NLMISC::CConfigFile::CVar &var)
-//{
-////#ifdef NL_OS_WINDOWS
-////	if (var.asBool() != SoundEnabled)
-////	{
-////		if (var.asBool()) initSound2();
-////		else releaseSound2();
-////	}
-////#endif
-//}
-//
-//void cbConfigFileFail(NLMISC::CConfigFile::CVar &var)
-//{
-//	//nlwarning("You can't modify the config variable '%s' at runtime for now, please restart the game", var.asString().c_str());
-//}
-//
-////#ifdef NL_OS_WINDOWS
-////void initSound2()
-////{
-////	AudioMixer = UAudioMixer::createAudioMixer ();
-////	std::string driverName;
-////	NLSOUND::UAudioMixer::TDriver driverType;
-////	if (!ConfigFile->exists("SoundDriver")) 
-////#ifdef NL_OS_WINDOWS
-////		driverType = NLSOUND::UAudioMixer::DriverFMod;
-////#elif defined (NL_OS_UNIX)
-////		driverType = NLSOUND::UAudioMixer::DriverOpenAl;
-////#else
-////		driverType = NLSOUND::UAudioMixer::DriverAuto;
-////#endif
-////	else 
-////	{
-////		driverName = ConfigFile->getVar("SoundDriver").asString();
-////		if (driverName == "Auto") driverType = NLSOUND::UAudioMixer::DriverAuto;
-////		else if (driverName == "FMod") driverType = NLSOUND::UAudioMixer::DriverFMod;
-////		else if (driverName == "DSound") driverType = NLSOUND::UAudioMixer::DriverDSound;
-////		else if (driverName == "OpenAl") driverType = NLSOUND::UAudioMixer::DriverOpenAl;
-////		else nlerror("SoundDriver value '%s' is invalid.", driverName.c_str());
-////	}
-////
-////	AudioMixer->init(
-////		ConfigFile->exists("SoundMaxTracks")
-////		? ConfigFile->getVar("SoundMaxTracks").asInt() : 32,
-////		ConfigFile->exists("SoundUseEax")
-////		? ConfigFile->getVar("SoundUseEax").asBool() : true,
-////		ConfigFile->exists("SoundUseADPCM")
-////		? ConfigFile->getVar("SoundUseADPCM").asBool() : true,
-////		NULL, false, driverType,
-////		ConfigFile->exists("SoundForceSoftware")
-////		? ConfigFile->getVar("SoundForceSoftware").asBool() : true);
-////
-////	ConfigFile->setCallback("SoundMaxTracks", cbConfigFileSoundMaxTracks);
-////	ConfigFile->setCallback("SoundUseEax", cbConfigFileFail);
-////	ConfigFile->setCallback("SoundUseADPCM", cbConfigFileFail);
-////	ConfigFile->setCallback("SoundForceSoftware", cbConfigFileFail);
-////	ConfigFile->setCallback("SoundDriver", cbConfigFileFail);
-////
-////	PlaylistManager = new SBCLIENT::CMusicPlaylistManager(AudioMixer, ConfigFile, "SoundPlaylist");
-////
-////	/* AudioMixer->loadSoundBuffers ("sounds.nss", &SoundIdArray);
-////	nlassert( SoundIdArray->size() == 2 );
-////	SoundId = (*SoundIdArray)[0];
-////	// StSoundId = (*SoundIdArray)[1]; */
-////	
-////	SoundEnabled = true;
-////}
-////#endif
-//
-//void initSound()
-//{
-////#ifdef NL_OS_WINDOWS
-////	if (ConfigFile->exists("SoundEnabled") ? ConfigFile->getVar("SoundEnabled").asBool() : false) initSound2();
-////	ConfigFile->setCallback("SoundEnabled", cbConfigFileSoundEnabled);
-////#endif
-//}
+// Functions
 //
+
+#ifdef SBCLIENT_WITH_SOUND
+
+void initSound2();
+void releaseSound2();
+
+void cbConfigFileSoundMaxTracks(NLMISC::CConfigFile::CVar &var)
+{
+	if (AudioMixer)
+		AudioMixer->changeMaxTrack(var.asInt());
+}
+
+void cbConfigFileSoundEnabled(NLMISC::CConfigFile::CVar &var)
+{
+	if (var.asBool() != SoundEnabled)
+	{
+		if (var.asBool())
+			initSound2();
+		else
+			releaseSound2();
+	}
+}
+
+void cbConfigFileMusicVolume(NLMISC::CConfigFile::CVar &var)
+{
+	if (AudioMixer)
+		AudioMixer->setMusicVolume(var.asFloat());
+}
+
+void cbConfigFileFail(NLMISC::CConfigFile::CVar &var)
+{
+	nlwarning("You can't modify the config variable '%s' at runtime for now, please restart the game", var.asString().c_str());
+}
+
+void initSound2()
+{
+	AudioMixer = UAudioMixer::createAudioMixer();
+	std::string driverName;
+	NLSOUND::UAudioMixer::TDriver driverType;
+	if (!ConfigFile->exists("SoundDriver"))
+#ifdef NL_OS_WINDOWS
+		driverType = NLSOUND::UAudioMixer::DriverFMod;
+#elif defined(NL_OS_UNIX)
+		driverType = NLSOUND::UAudioMixer::DriverOpenAl;
+#else
+		driverType = NLSOUND::UAudioMixer::DriverAuto;
+#endif
+	else
+	{
+		driverName = ConfigFile->getVar("SoundDriver").asString();
+		if (driverName == "Auto")
+			driverType = NLSOUND::UAudioMixer::DriverAuto;
+		else if (driverName == "FMod")
+			driverType = NLSOUND::UAudioMixer::DriverFMod;
+		else if (driverName == "DSound")
+			driverType = NLSOUND::UAudioMixer::DriverDSound;
+		else if (driverName == "OpenAl")
+			driverType = NLSOUND::UAudioMixer::DriverOpenAl;
+		else
+			nlerror("SoundDriver value '%s' is invalid.", driverName.c_str());
+	}
+
+	AudioMixer->init(
+	    ConfigFile->exists("SoundMaxTracks")
+	        ? ConfigFile->getVar("SoundMaxTracks").asInt()
+	        : 32,
+	    ConfigFile->exists("SoundUseEax")
+	        ? ConfigFile->getVar("SoundUseEax").asBool()
+	        : true,
+	    ConfigFile->exists("SoundUseADPCM")
+	        ? ConfigFile->getVar("SoundUseADPCM").asBool()
+	        : true,
+	    NULL, true, driverType,
+	    ConfigFile->exists("SoundForceSoftware")
+	        ? ConfigFile->getVar("SoundForceSoftware").asBool()
+	        : true);
+
+	ConfigFile->setCallback("SoundMaxTracks", cbConfigFileSoundMaxTracks);
+	ConfigFile->setCallback("SoundUseEax", cbConfigFileFail);
+	ConfigFile->setCallback("SoundUseADPCM", cbConfigFileFail);
+	ConfigFile->setCallback("SoundForceSoftware", cbConfigFileFail);
+	ConfigFile->setCallback("SoundDriver", cbConfigFileFail);
+	CConfiguration::setAndCallback("MusicVolume", cbConfigFileMusicVolume);
+
+	// PlaylistManager = new SBCLIENT::CMusicPlaylistManager(AudioMixer, ConfigFile, "SoundPlaylist");
+
+	/* AudioMixer->loadSoundBuffers ("sounds.nss", &SoundIdArray);
+	nlassert( SoundIdArray->size() == 2 );
+	SoundId = (*SoundIdArray)[0];
+	// StSoundId = (*SoundIdArray)[1]; */
+
+	SoundEnabled = true;
+}
+
+void releaseSound2()
+{
+	SoundEnabled = false;
+	ConfigFile->setCallback("SoundMaxTracks", NULL);
+	ConfigFile->setCallback("SoundUseEax", NULL);
+	ConfigFile->setCallback("SoundUseADPCM", NULL);
+	ConfigFile->setCallback("SoundForceSoftware", NULL);
+	ConfigFile->setCallback("SoundDriver", NULL);
+	// delete PlaylistManager;
+	// PlaylistManager = NULL;
+	delete AudioMixer;
+	AudioMixer = NULL;
+}
+
+#endif
+
+void initSound()
+{
+#ifdef SBCLIENT_WITH_SOUND
+	if (ConfigFile->exists("SoundEnabled") ? ConfigFile->getVar("SoundEnabled").asBool() : false)
+		initSound2();
+	ConfigFile->setCallback("SoundEnabled", cbConfigFileSoundEnabled);
+#endif
+}
+
 //void playSound (CEntity &entity, TSoundId id)
 //{
 ///*	entity.Source = AudioMixer->createSource (id);
 //	entity.Source->setLooping (true);
 //	entity.Source->play ();
 //*/}
-//
+
 //void deleteSound (CEntity &entity)
 //{
 ///*	if (entity.Source != NULL)
@@ -162,42 +197,36 @@ using namespace NLSOUND;
 //		entity.Source = NULL;
 //	}
 //*/}
-//
-//void updateSound()
-//{
-////#ifdef NL_OS_WINDOWS
-////	if (SoundEnabled)
-////	{
-////		PlaylistManager->update(DiffTime);
-////		AudioMixer->update();
-////	}
-////#endif
-//}
-//
-////#ifdef NL_OS_WINDOWS
-////void releaseSound2()
-////{		
-////	SoundEnabled = false;
-////	ConfigFile->setCallback("SoundMaxTracks", NULL);
-////	ConfigFile->setCallback("SoundUseEax", NULL);
-////	ConfigFile->setCallback("SoundUseADPCM", NULL);
-////	ConfigFile->setCallback("SoundForceSoftware", NULL);
-////	ConfigFile->setCallback("SoundDriver", NULL);
-////	delete PlaylistManager;
-////	PlaylistManager = NULL;
-////	delete AudioMixer;
-////	AudioMixer = NULL;
-////}
-////#endif
-//
-//void releaseSound()
-//{
-////#ifdef NL_OS_WINDOWS
-////	ConfigFile->setCallback("SoundEnabled", NULL);
-////	if (SoundEnabled) releaseSound2();
-////#endif
-//}
-//
+
+void updateSound()
+{
+#ifdef SBCLIENT_WITH_SOUND
+	if (SoundEnabled)
+	{
+		// PlaylistManager->update(DiffTime);
+		AudioMixer->update();
+	}
+	#endif
+}
+
+void releaseSound()
+{
+#ifdef SBCLIENT_WITH_SOUND
+	ConfigFile->setCallback("SoundEnabled", NULL);
+	if (SoundEnabled) releaseSound2();
+#endif
+}
+
+void playMusic(const char *file)
+{
+#ifdef SBCLIENT_WITH_SOUND
+	if (AudioMixer)
+		AudioMixer->playMusic(file, 1000, true, true);
+#endif
+}
+
+} /* namespace SBCLIENT */
+
 ////#ifdef NL_OS_WINDOWS
 ////
 ////void playMusic(sint32 playlist, sint32 track)
@@ -211,35 +240,38 @@ using namespace NLSOUND;
 ////	if (SoundEnabled)
 ////		PlaylistManager->setVolume(playlist, volume);
 ////}
-////
-////NLMISC_COMMAND(music_bg,"background music","")
-////{
-////	if (args.size() != 0) return false;
-////	playMusic(SBCLIENT_MUSIC_BACKGROUND);
-////	return true;
-////}
-////
-////NLMISC_COMMAND(music_bg_beat,"background music with beat","")
-////{
-////	if (args.size() != 0) return false;
-////	PlaylistManager->playMusic(SBCLIENT_MUSIC_BACKGROUND_BEAT);
-////	return true;
-////}
-////
-////NLMISC_COMMAND(music_wait,"loading music","")
-////{
-////	if (args.size() != 0) return false;
-////	PlaylistManager->playMusic(SBCLIENT_MUSIC_WAIT);
-////	return true;
-////}
-////
-////NLMISC_COMMAND(music_login,"login screen music","")
-////{
-////	if (args.size() != 0) return false;
-////	PlaylistManager->playMusic(SBCLIENT_MUSIC_LOGIN);
-////	return true;
-////}
-////
+
+NLMISC_COMMAND(music_bg,"background music","")
+{
+	if (args.size() != 0) return false;
+	SBCLIENT::playMusic(SBCLIENT_MUSIC_BACKGROUND);
+	return true;
+}
+
+NLMISC_COMMAND(music_bg_beat,"background music with beat","")
+{
+	if (args.size() != 0)
+		return false;
+	SBCLIENT::playMusic(SBCLIENT_MUSIC_BACKGROUND_BEAT);
+	return true;
+}
+
+NLMISC_COMMAND(music_wait,"loading music","")
+{
+	if (args.size() != 0)
+		return false;
+	SBCLIENT::playMusic(SBCLIENT_MUSIC_WAIT);
+	return true;
+}
+
+NLMISC_COMMAND(music_login,"login screen music","")
+{
+	if (args.size() != 0)
+		return false;
+	SBCLIENT::playMusic(SBCLIENT_MUSIC_LOGIN);
+	return true;
+}
+
 ////#endif 
 
-#endif // SBCLIENT_WITH_SOUND
+/* end of file */
diff --git a/code/snowballs2/client/src/sound.h b/code/snowballs2/client/src/sound.h
index 2862d141c..34b0d6723 100644
--- a/code/snowballs2/client/src/sound.h
+++ b/code/snowballs2/client/src/sound.h
@@ -35,35 +35,43 @@
 // Defines
 // 
 
-//#define SBCLIENT_MUSIC_WAIT (0), (0)
-//#define SBCLIENT_MUSIC_LOGIN (1), (0)
-//#define SBCLIENT_MUSIC_BACKGROUND (2), (0)
-//#define SBCLIENT_MUSIC_BACKGROUND_BEAT (2), (1)
+#define SBCLIENT_MUSIC_WAIT "xtarsia_evil-snowballs_wait.ogg"
+#define SBCLIENT_MUSIC_LOGIN "xtarsia_evil-snowballs_login.ogg"
+#define SBCLIENT_MUSIC_BACKGROUND "xtarsia_evil-snowballs_beat.ogg" /* "xtarsia_evil-snowballs_game.ogg" */
+#define SBCLIENT_MUSIC_BACKGROUND_BEAT "xtarsia_evil-snowballs_beat.ogg"
+
+namespace SBCLIENT {
 
 //
 // External variables
 //
 
-//extern NLSOUND::UAudioMixer *AudioMixer;
+#ifdef SBCLIENT_WITH_SOUND
+extern NLSOUND::UAudioMixer *AudioMixer;
 //extern NLSOUND::TSoundId SoundId;
+#endif
+
 //
-////
-//// External functions
-////
+// External functions
 //
+
 //void playMusic(sint32 playlist, sint32 track);
 //void setMusicVolume(sint32 playlist, float volume);
-//
-//void initSound();
-//void updateSound();
-//void releaseSound();
-//
+
+void initSound();
+void updateSound();
+void releaseSound();
+
+void playMusic(const char *file);
+
 //// Set and play a sound on an entity
 //void playSound(CEntity &entity, NLSOUND::TSoundId id);
-//
+
 //// Remove the sound system link to the entity
 //void deleteSound(CEntity &entity);
 
+} /* namespace SBCLIENT */
+
 #endif // SBCLIENT_SOUND_H
 
 /* End of sound.h */ // duh

From fa86408d50e34d55cf58c832ffc8040afb44791e Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Wed, 1 May 2019 13:13:35 +0300
Subject: [PATCH 67/75] Changed: fix for vc2013

--HG--
branch : develop
---
 code/nel/include/nel/misc/common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h
index e1b3fb9f1..350abc7f3 100644
--- a/code/nel/include/nel/misc/common.h
+++ b/code/nel/include/nel/misc/common.h
@@ -277,7 +277,7 @@ template <class T> T trimRightWhiteSpaces (const T &str)
 }
 
 // if both first and last char are quotes (' or "), then remove them
-template <class T> T trimQuotes (const T&str)
+template <class T> T trimQuotes (const T &str)
 {
 	typename T::size_type size = str.size();
 	if (size == 0)

From 8f124b3066b9435ac2ffb2a3f85622f950bf6afa Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 3 May 2019 00:26:12 +0300
Subject: [PATCH 68/75] Changed: Add extra url parameters only for trusted
 domain requests

--HG--
branch : develop
---
 code/ryzom/client/src/interface_v3/group_html_webig.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp
index ea885f17b..8d6ea05af 100644
--- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp
+++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp
@@ -71,6 +71,9 @@ static string getWebAuthKey()
 
 void addWebIGParams (string &url, bool trustedDomain)
 {
+	// no extras parameters added to url if not in trusted domains list
+	if (!trustedDomain) return;
+
 	if(!UserEntity || !NetMngr.getLoginCookie().isValid()) return;
 
 	uint32 cid = NetMngr.getLoginCookie().getUserId() * 16 + PlayerSelectedSlot;

From fed9a2b0c955646b0da8823b71b3b2d32177a878 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 3 May 2019 00:26:12 +0300
Subject: [PATCH 69/75] Changed: Remove old libwww elements

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_html.h   |    1 -
 code/nel/include/nel/gui/libwww.h       |  384 +++-----
 code/nel/include/nel/gui/libwww_types.h | 1075 -----------------------
 code/nel/src/gui/group_html.cpp         |    1 -
 code/nel/src/gui/html_parser.cpp        |   10 +-
 code/nel/src/gui/libwww.cpp             |  465 ++++------
 code/nel/src/gui/libwww_types.cpp       |  804 -----------------
 7 files changed, 302 insertions(+), 2438 deletions(-)
 delete mode 100644 code/nel/include/nel/gui/libwww_types.h
 delete mode 100644 code/nel/src/gui/libwww_types.cpp

diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index e5a2670a4..2c6737446 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -23,7 +23,6 @@
 #include "nel/gui/group_tree.h"
 #include "nel/gui/ctrl_button.h"
 #include "nel/gui/group_table.h"
-#include "nel/gui/libwww_types.h"
 #include "nel/gui/html_element.h"
 #include "nel/gui/css_style.h"
 
diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h
index 74227305c..e713f3c81 100644
--- a/code/nel/include/nel/gui/libwww.h
+++ b/code/nel/include/nel/gui/libwww.h
@@ -21,7 +21,6 @@
 #define CL_LIB_WWW_H
 
 #include "nel/misc/rgba.h"
-#include "nel/gui/libwww_types.h"
 
 // forward declaration to avoid curl.h inclusion everywhere
 typedef void CURL;
@@ -32,251 +31,146 @@ namespace NLGUI
 	class CCtrlScroll;
 	class CGroupList;
 
-	// ***************************************************************************
+	// List of HTML elements. Does not need to be sorted
+	typedef enum _HTMLElement {
+		HTML_HTML,
+		HTML_BODY,
+		// meta
+		HTML_BASE,
+		HTML_HEAD,
+		HTML_LINK,
+		HTML_META,
+		HTML_STYLE,
+		HTML_TITLE,
+		// content sectioning
+		HTML_ADDRESS,
+		HTML_ARTICLE,
+		HTML_ASIDE,
+		HTML_FOOTER,
+		HTML_HEADER,
+		HTML_H1,
+		HTML_H2,
+		HTML_H3,
+		HTML_H4,
+		HTML_H5,
+		HTML_H6,
+		HTML_HGROUP,
+		HTML_MAIN,
+		HTML_NAV,
+		HTML_SECTION,
+		// text content
+		HTML_BLOCKQUOTE,
+		HTML_DD,
+		HTML_DIR,
+		HTML_DIV,
+		HTML_DL,
+		HTML_DT,
+		HTML_FIGCAPTION,
+		HTML_FIGURE,
+		HTML_HR,
+		HTML_LI,
+		HTML_OL,
+		HTML_P,
+		HTML_PRE,
+		HTML_UL,
+		// inline text
+		HTML_A,
+		HTML_ABBR,
+		HTML_B,
+		HTML_BDI,
+		HTML_BDO,
+		HTML_BR,
+		HTML_CITE,
+		HTML_CODE,
+		HTML_DATA,
+		HTML_DFN,
+		HTML_EM,
+		HTML_I,
+		HTML_KBD,
+		HTML_MARK,
+		HTML_Q,
+		HTML_RB,
+		HTML_RP,
+		HTML_RT,
+		HTML_RTC,
+		HTML_RUBY,
+		HTML_S,
+		HTML_SAMP,
+		HTML_SMALL,
+		HTML_SPAN,
+		HTML_STRONG,
+		HTML_SUB,
+		HTML_SUP,
+		HTML_TIME,
+		HTML_TT,
+		HTML_U,
+		HTML_VAR,
+		HTML_WBR,
+		// image, multimedia
+		HTML_AREA,
+		HTML_AUDIO,
+		HTML_IMG,
+		HTML_MAP,
+		HTML_TRACK,
+		HTML_VIDEO,
+		// embedded content
+		HTML_APPLET,
+		HTML_EMBED,
+		HTML_IFRAME,
+		HTML_NOEMBED,
+		HTML_OBJECT,
+		HTML_PARAM,
+		HTML_PICTURE,
+		HTML_SOURCE,
+		// scripting
+		HTML_CANVAS,
+		HTML_NOSCRIPT,
+		HTML_SCRIPT,
+		// demarcating edits
+		HTML_DEL,
+		HTML_INS,
+		// table
+		HTML_CAPTION,
+		HTML_COL,
+		HTML_COLGROUP,
+		HTML_TABLE,
+		HTML_TBODY,
+		HTML_TD,
+		HTML_TFOOT,
+		HTML_TH,
+		HTML_THEAD,
+		HTML_TR,
+		// forms
+		HTML_BUTTON,
+		HTML_DATALIST,
+		HTML_FIELDSET,
+		HTML_FORM,
+		HTML_INPUT,
+		HTML_LABEL,
+		HTML_LEGEND,
+		HTML_METER,
+		HTML_OPTGROUP,
+		HTML_OPTION,
+		HTML_OUTPUT,
+		HTML_PROGRESS,
+		HTML_SELECT,
+		HTML_TEXTAREA,
+		// interactive elements
+		HTML_DETAILS,
+		HTML_DIALOG,
+		HTML_MENU,
+		HTML_MENUITEM,
+		HTML_SUMMARY,
+		// -- tags for ryzom --
+		HTML_FONT,
+		HTML_LUA,
+		// last entry for unknown elements
+		HTML_NB_ELEMENTS
+	} HTMLElement;
 
-	// Legacy function from libwww
-	SGML_dtd * HTML_dtd (void);
-
-	// Init the libwww
-	void initLibWWW();
-
-	// ***************************************************************************
-
-	// Some DTD table
-
-	// Here, modify the DTD table to change the HTML parser (add new tags for exemples)
-
-	#undef HTML_ATTR
-	#define HTML_ATTR(t,a) MY_HTML_##t##_##a
-
-	enum
-	{
-		HTML_ATTR(HTML,DIR) = 0,
-		HTML_ATTR(HTML,LANG),
-		HTML_ATTR(HTML,VERSION),
-		HTML_ATTR(HTML,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(A,ACCESSKEY) = 0,
-			HTML_ATTR(A,CHARSET),
-			HTML_ATTR(A,CLASS),
-			HTML_ATTR(A,COORDS),
-			HTML_ATTR(A,DIR),
-			HTML_ATTR(A,HREF),
-			HTML_ATTR(A,HREFLANG),
-			HTML_ATTR(A,ID),
-			HTML_ATTR(A,NAME),
-			HTML_ATTR(A,REL),
-			HTML_ATTR(A,REV),
-			HTML_ATTR(A,SHAPE),
-			HTML_ATTR(A,STYLE),
-			HTML_ATTR(A,TABINDEX),
-			HTML_ATTR(A,TARGET),
-			HTML_ATTR(A,TYPE),
-			HTML_ATTR(A,TITLE),
-			HTML_ATTR(A,Z_ACTION_CATEGORY),
-			HTML_ATTR(A,Z_ACTION_PARAMS),
-			HTML_ATTR(A,Z_ACTION_SHORTCUT),
-	};
-
-	enum
-	{
-		HTML_ATTR(TABLE,ALIGN) = 0,
-			HTML_ATTR(TABLE,BGCOLOR),
-			HTML_ATTR(TABLE,BORDER),
-			HTML_ATTR(TABLE,BORDERCOLOR),
-			HTML_ATTR(TABLE,CELLPADDING),
-			HTML_ATTR(TABLE,CELLSPACING),
-			HTML_ATTR(TABLE,CLASS),
-			HTML_ATTR(TABLE,DIR),
-			HTML_ATTR(TABLE,FRAME),
-			HTML_ATTR(TABLE,ID),
-			HTML_ATTR(TABLE,L_MARGIN),
-			HTML_ATTR(TABLE,LANG),
-			HTML_ATTR(TABLE,NOWRAP),
-			HTML_ATTR(TABLE,RULES),
-			HTML_ATTR(TABLE,SUMMARY),
-			HTML_ATTR(TABLE,STYLE),
-			HTML_ATTR(TABLE,TITLE),
-			HTML_ATTR(TABLE,VALIGN),
-			HTML_ATTR(TABLE,WIDTH)
-	};
-
-	enum
-	{
-		HTML_ATTR(TR,ALIGN) = 0,
-			HTML_ATTR(TR,BGCOLOR),
-			HTML_ATTR(TR,L_MARGIN),
-			HTML_ATTR(TR,NOWRAP),
-			HTML_ATTR(TR,VALIGN),
-			HTML_ATTR(TR,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(TD,ABBR) = 0,
-			HTML_ATTR(TD,ALIGN),
-			HTML_ATTR(TD,AXIS),
-			HTML_ATTR(TD,BGCOLOR),
-			HTML_ATTR(TD,CHAR),
-			HTML_ATTR(TD,CHAROFF),
-			HTML_ATTR(TD,CLASS),
-			HTML_ATTR(TD,COLSPAN),
-			HTML_ATTR(TD,DIR),
-			HTML_ATTR(TD,ID),
-			HTML_ATTR(TD,HEADERS),
-			HTML_ATTR(TD,HEIGHT),
-			HTML_ATTR(TD,L_MARGIN),
-			HTML_ATTR(TD,LANG),
-			HTML_ATTR(TD,NOWRAP),
-			HTML_ATTR(TD,ROWSPAN),
-			HTML_ATTR(TD,SCOPE),
-			HTML_ATTR(TD,STYLE),
-			HTML_ATTR(TD,TITLE),
-			HTML_ATTR(TD,VALIGN),
-			HTML_ATTR(TD,WIDTH),
-	};
-
-	enum
-	{
-		HTML_ATTR(IMG,ALIGN) = 0,
-			HTML_ATTR(IMG,ALT),
-			HTML_ATTR(IMG,BORDER),
-			HTML_ATTR(IMG,CLASS),
-			HTML_ATTR(IMG,DIR),
-			HTML_ATTR(IMG,GLOBAL_COLOR),
-			HTML_ATTR(IMG,HEIGHT),
-			HTML_ATTR(IMG,HSPACE),
-			HTML_ATTR(IMG,ID),
-			HTML_ATTR(IMG,ISMAP),
-			HTML_ATTR(IMG,LANG),
-			HTML_ATTR(IMG,LONGDESC),
-			HTML_ATTR(IMG,SRC),
-			HTML_ATTR(IMG,STYLE),
-			HTML_ATTR(IMG,TITLE),
-			HTML_ATTR(IMG,USEMAP),
-			HTML_ATTR(IMG,VSPACE),
-			HTML_ATTR(IMG,WIDTH),
-			// not sorted to keep enum values
-			HTML_ATTR(IMG,DATA_OVER_SRC),
-	};
-
-	enum
-	{
-		HTML_ATTR(INPUT,ACCEPT) = 0,
-			HTML_ATTR(INPUT,ACCESSKEY),
-			HTML_ATTR(INPUT,ALIGN),
-			HTML_ATTR(INPUT,ALT),
-			HTML_ATTR(INPUT,CHECKED),
-			HTML_ATTR(INPUT,CLASS),
-			HTML_ATTR(INPUT,DIR),
-			HTML_ATTR(INPUT,DISABLED),
-			HTML_ATTR(INPUT,GLOBAL_COLOR),
-			HTML_ATTR(INPUT,ID),
-			HTML_ATTR(INPUT,LANG),
-			HTML_ATTR(INPUT,MAXLENGTH),
-			HTML_ATTR(INPUT,NAME),
-			HTML_ATTR(INPUT,READONLY),
-			HTML_ATTR(INPUT,SIZE),
-			HTML_ATTR(INPUT,SRC),
-			HTML_ATTR(INPUT,STYLE),
-			HTML_ATTR(INPUT,TABINDEX),
-			HTML_ATTR(INPUT,TITLE),
-			HTML_ATTR(INPUT,TYPE),
-			HTML_ATTR(INPUT,USEMAP),
-			HTML_ATTR(INPUT,VALUE),
-			HTML_ATTR(INPUT,Z_BTN_TMPL),
-			HTML_ATTR(INPUT,Z_INPUT_TMPL),
-			HTML_ATTR(INPUT,Z_INPUT_WIDTH),
-	};
-
-	enum
-	{
-		HTML_ATTR(TEXTAREA,CLASS) = 0,
-		HTML_ATTR(TEXTAREA,COLS),
-		HTML_ATTR(TEXTAREA,DIR),
-		HTML_ATTR(TEXTAREA,DISABLED),
-		HTML_ATTR(TEXTAREA,ID),
-		HTML_ATTR(TEXTAREA,LANG),
-		HTML_ATTR(TEXTAREA,MAXLENGTH),
-		HTML_ATTR(TEXTAREA,NAME),
-		HTML_ATTR(TEXTAREA,READONLY),
-		HTML_ATTR(TEXTAREA,ROWS),
-		HTML_ATTR(TEXTAREA,STYLE),
-		HTML_ATTR(TEXTAREA,TABINDEX),
-		HTML_ATTR(TEXTAREA,TITLE),
-		HTML_ATTR(TEXTAREA,Z_INPUT_TMPL),
-	};
-
-	enum
-	{
-		HTML_ATTR(P,QUICK_HELP_CONDITION) = 0,
-			HTML_ATTR(P,QUICK_HELP_EVENTS),
-			HTML_ATTR(P,QUICK_HELP_LINK),
-			HTML_ATTR(P,NAME),
-			HTML_ATTR(P,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(DIV,CLASS) = 0,
-		HTML_ATTR(DIV,ID),
-		HTML_ATTR(DIV,NAME),
-		HTML_ATTR(DIV,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(SPAN,CLASS) = 0,
-		HTML_ATTR(SPAN,ID),
-		HTML_ATTR(SPAN,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(H1,CLASS) = 0,
-		HTML_ATTR(H1,ID),
-		HTML_ATTR(H1,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(H2,CLASS) = 0,
-		HTML_ATTR(H2,ID),
-		HTML_ATTR(H2,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(H3,CLASS) = 0,
-		HTML_ATTR(H3,ID),
-		HTML_ATTR(H3,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(H4,CLASS) = 0,
-		HTML_ATTR(H4,ID),
-		HTML_ATTR(H4,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(H5,CLASS) = 0,
-		HTML_ATTR(H5,ID),
-		HTML_ATTR(H5,STYLE),
-	};
-
-	enum
-	{
-		HTML_ATTR(H6,CLASS) = 0,
-		HTML_ATTR(H6,ID),
-		HTML_ATTR(H6,STYLE),
-	};
-
-	#undef HTML_ATTR
+	// case insensitive lookup for HTMLElement enum by name
+	// return HTML_NB_ELEMENTS if no match
+	HTMLElement htmlElementLookup(const char *name);
 
 	// ***************************************************************************
 	// Read HTML color value from src and set dest
diff --git a/code/nel/include/nel/gui/libwww_types.h b/code/nel/include/nel/gui/libwww_types.h
deleted file mode 100644
index 01f6eb534..000000000
--- a/code/nel/include/nel/gui/libwww_types.h
+++ /dev/null
@@ -1,1075 +0,0 @@
-/**
-                                                        libwww Copyright Notice
-   [This notice should be placed within redistributed or derivative software
-   code when appropriate. This particular formulation of W3C's notice for
-   inclusion in libwww code became active on August 14 1998.]
-
-                            LIBWWW COPYRIGHT NOTICE
-
-   libwww: W3C's implementation of HTTP can be found at:
-   http://www.w3.org/Library/
-
-                         Copyright ¨ 1995-2002 World Wide Web Consortium,
-                         (Massachusetts Institute of Technology, Institut
-                         National de Recherche en Informatique et en
-                         Automatique, Keio University). All Rights Reserved.
-                         This program is distributed under the W3C's
-                         Intellectual Property License. This program is
-                         distributed in the hope that it will be useful, but
-                         WITHOUT ANY WARRANTY; without even the implied
-                         warranty of MERCHANTABILITY or FITNESS FOR A
-                         PARTICULAR PURPOSE. See W3C License
-                         http://www.w3.org/Consortium/Legal/ for more details.
-
-                         Copyright ¨ 1995 CERN. "This product includes computer
-                         software created and made available by CERN. This
-                         acknowledgment shall be mentioned in full in any
-                         product which includes the CERN computer software
-                         included herein or parts thereof."
-
- *****************************************************************************/
-
-#ifndef CL_LIB_WWW_TYPES_H
-#define CL_LIB_WWW_TYPES_H
-
-#include <string>
-
-//
-// LibWWW elements
-// - order must be kept for backward compatibility, new tags can be added to the end
-typedef enum _HTMLElement {
-	HTML_A = 0,
-	HTML_ABBR,
-	HTML_ACRONYM,
-	HTML_ADDRESS,
-	HTML_APPLET,
-	HTML_AREA,
-	HTML_B,
-	HTML_BASE,
-	HTML_BASEFONT,
-	HTML_BDO,
-	HTML_BIG,
-	HTML_BLOCKQUOTE,
-	HTML_BODY,
-	HTML_BR,
-	HTML_BUTTON,
-	HTML_CAPTION,
-	HTML_CENTER,
-	HTML_CITE,
-	HTML_CODE,
-	HTML_COL,
-	HTML_COLGROUP,
-	HTML_DD,
-	HTML_DEL,
-	HTML_DFN,
-	HTML_DIR,
-	HTML_DIV,
-	HTML_DL,
-	HTML_DT,
-	HTML_EM,
-	HTML_FIELDSET,
-	HTML_FONT,
-	HTML_FORM,
-	HTML_FRAME,
-	HTML_FRAMESET,
-	HTML_H1,
-	HTML_H2,
-	HTML_H3,
-	HTML_H4,
-	HTML_H5,
-	HTML_H6,
-	HTML_HEAD,
-	HTML_HR,
-	HTML_HTML,
-	HTML_I,
-	HTML_IFRAME,
-	HTML_IMG,
-	HTML_INPUT,
-	HTML_INS,
-	HTML_ISINDEX,
-	HTML_KBD,
-	HTML_LABEL,
-	HTML_LEGEND,
-	HTML_LI,
-	HTML_LINK,
-	HTML_MAP,
-	HTML_MENU,
-	HTML_META,
-	HTML_NEXTID,	/* !!! */
-	HTML_NOFRAMES,
-	HTML_NOSCRIPT,
-	HTML_OBJECT,
-	HTML_OL,
-	HTML_OPTGROUP,
-	HTML_OPTION,
-	HTML_P,
-	HTML_PARAM,
-	HTML_PRE,
-	HTML_Q,
-	HTML_S,
-	HTML_SAMP,
-	HTML_SCRIPT,
-	HTML_SELECT,
-	HTML_SMALL,
-	HTML_SPAN,
-	HTML_STRIKE,
-	HTML_STRONG,
-	HTML_STYLE,
-	HTML_SUB,
-	HTML_SUP,
-	HTML_TABLE,
-	HTML_TBODY,
-	HTML_TD,
-	HTML_TEXTAREA,
-	HTML_TFOOT,
-	HTML_TH,
-	HTML_THEAD,
-	HTML_TITLE,
-	HTML_TR,
-	HTML_TT,
-	HTML_U,
-	HTML_UL,
-	HTML_VAR,
-	// new tags
-	HTML_LUA,
-	// this must be the last entry
-	HTML_ELEMENTS
-} HTMLElement;
-
-
-#define HTML_ATTR(t,a)		HTML_##t##_##a
-#define HTML_ATTRIBUTES(t)	HTML_##t##_ATTRIBUTES
-
-/*
-   (
-   A
-   )
-   */
-
-enum _HTML_A_Attributes {
-	HTML_ATTR(A,ACCESSKEY) = 0,
-	HTML_ATTR(A,CHARSET),
-	HTML_ATTR(A,CLASS),
-	HTML_ATTR(A,COORDS),
-	HTML_ATTR(A,DIR),
-	HTML_ATTR(A,HREF),
-	HTML_ATTR(A,HREFLANG),
-	HTML_ATTR(A,ID),
-	HTML_ATTR(A,NAME),
-	HTML_ATTR(A,REL),
-	HTML_ATTR(A,REV),
-	HTML_ATTR(A,SHAPE),
-	HTML_ATTR(A,STYLE),
-	HTML_ATTR(A,TABINDEX),
-	HTML_ATTR(A,TARGET),
-	HTML_ATTR(A,TYPE),
-	HTML_ATTR(A,TITLE),
-	HTML_ATTR(A,Z_ACTION_CATEGORY), // NLGUI
-	HTML_ATTR(A,Z_ACTION_PARANS), // NLGUI
-	HTML_ATTR(A,Z_ACTION_SHORTCUT), // NLGUI
-	HTML_ATTRIBUTES(A)
-};
-
-/*
-   (
-   APPLET - Deprecated
-   )
-   */
-
-enum _HTML_APPLET_Attributes {
-	HTML_ATTR(APPLET,ALIGN) = 0,
-	HTML_ATTR(APPLET,ALT),
-	HTML_ATTR(APPLET,ARCHIVE),
-	HTML_ATTR(APPLET,CLASS),
-	HTML_ATTR(APPLET,CODE),
-	HTML_ATTR(APPLET,CODEBASE),
-	HTML_ATTR(APPLET,HEIGHT),
-	HTML_ATTR(APPLET,HSPACE),
-	HTML_ATTR(APPLET,ID),
-	HTML_ATTR(APPLET,NAME),
-	HTML_ATTR(APPLET,OBJECT),
-	HTML_ATTR(APPLET,STYLE),
-	HTML_ATTR(APPLET,TITLE),
-	HTML_ATTR(APPLET,VSPACE),
-	HTML_ATTR(APPLET,WIDTH),
-	HTML_ATTRIBUTES(APPLET)
-};
-
-/*
-   (
-   AREA
-   )
-   */
-
-enum _HTML_AREA_Attributes {
-	HTML_ATTR(AREA,ACCESSKEY) = 0,
-	HTML_ATTR(AREA,ALT),
-	HTML_ATTR(AREA,CLASS),
-	HTML_ATTR(AREA,COORDS),
-	HTML_ATTR(AREA,DIR),
-	HTML_ATTR(AREA,HREF),
-	HTML_ATTR(AREA,ID),
-	HTML_ATTR(AREA,NAME),
-	HTML_ATTR(AREA,NOHREF),
-	HTML_ATTR(AREA,LANG),
-	HTML_ATTR(AREA,SHAPE),
-	HTML_ATTR(AREA,STYLE),
-	HTML_ATTR(AREA,TABINDEX),
-	HTML_ATTR(AREA,TARGET),
-	HTML_ATTR(AREA,TITLE),
-	HTML_ATTRIBUTES(AREA)
-};
-
-
-/*
-   (
-   BASE
-   )
-   */
-
-enum _HTML_BASE_Attributes {
-	HTML_ATTR(BASE,HREF) = 0,
-	HTML_ATTR(BASE,TARGET),
-	HTML_ATTRIBUTES(BASE)
-};
-
-/*
-   (
-   BDO
-   )
-   */
-
-enum _HTML_BDO_Attributes {
-	HTML_ATTR(BDO,CLASS) = 0,
-	HTML_ATTR(BDO,DIR),
-	HTML_ATTR(BDO,ID),
-	HTML_ATTR(BDO,LANG),
-	HTML_ATTR(BDO,STYLE),
-	HTML_ATTR(BDO,TITLE),
-	HTML_ATTRIBUTES(BDO)
-};
-
-/*
-   (
-   BLOCKQUOTE
-   )
-   */
-
-enum _HTML_BQ_Attributes {
-	HTML_ATTR(BQ,CITE) = 0,
-	HTML_ATTR(BQ,CLASS),
-	HTML_ATTR(BQ,DIR),
-	HTML_ATTR(BQ,ID),
-	HTML_ATTR(BQ,LANG),
-	HTML_ATTR(BQ,STYLE),
-	HTML_ATTR(BQ,TITLE),
-	HTML_ATTRIBUTES(BQ)
-};
-
-/*
-   (
-   BODY
-   )
-   */
-
-enum _HTML_BODY_Attributes {
-	HTML_ATTR(BODY,ALINK) = 0,
-	HTML_ATTR(BODY,BACKGROUND),
-	HTML_ATTR(BODY,BGCOLOR),
-	HTML_ATTR(BODY,CLASS),
-	HTML_ATTR(BODY,DIR),
-	HTML_ATTR(BODY,ID),
-	HTML_ATTR(BODY,LANG),
-	HTML_ATTR(BODY,LINK),
-	HTML_ATTR(BODY,STYLE),
-	HTML_ATTR(BODY,TEXT),
-	HTML_ATTR(BODY,TITLE),
-	HTML_ATTR(BODY,VLINK),
-	HTML_ATTRIBUTES(BODY)
-};
-
-/*
-   (
-   BR
-   )
-   */
-
-enum _HTML_BR_Attributes {
-	HTML_ATTR(BR,CLASS) = 0,
-	HTML_ATTR(BR,CLEAR),
-	HTML_ATTR(BR,ID),
-	HTML_ATTR(BR,STYLE),
-	HTML_ATTR(BR,TITLE),
-	HTML_ATTRIBUTES(BR)
-};
-
-/*
-   (
-   BUTTON
-   )
-   */
-
-enum _HTML_BUTTON_Attributes {
-	HTML_ATTR(BUTTON,ACCESSKEY) = 0,
-	HTML_ATTR(BUTTON,CLASS),
-	HTML_ATTR(BUTTON,DIR),
-	HTML_ATTR(BUTTON,DISABLED),
-	HTML_ATTR(BUTTON,ID),
-	HTML_ATTR(BUTTON,LANG),
-	HTML_ATTR(BUTTON,NAME),
-	HTML_ATTR(BUTTON,STYLE),
-	HTML_ATTR(BUTTON,TABINDEX),
-	HTML_ATTR(BUTTON,TITLE),
-	HTML_ATTR(BUTTON,TYPE),
-	HTML_ATTR(BUTTON,VALUE),
-	HTML_ATTRIBUTES(BUTTON)
-};
-
-/*
-   (
-   COL
-   )
-   */
-
-enum _HTML_COL_Attributes {
-	HTML_ATTR(COL,CLASS) = 0,
-	HTML_ATTR(COL,DIR),
-	HTML_ATTR(COL,ID),
-	HTML_ATTR(COL,LANG),
-	HTML_ATTR(COL,SPAN),
-	HTML_ATTR(COL,STYLE),
-	HTML_ATTR(COL,TITLE),
-	HTML_ATTR(COL,WIDTH),
-	HTML_ATTRIBUTES(COL)
-};
-
-/*
-   (
-   DEL, INS
-   )
-   */
-
-enum _HTML_CHANGES_Attributes {
-	HTML_ATTR(CHANGES,CITE) = 0,
-	HTML_ATTR(CHANGES,CLASS),
-	HTML_ATTR(CHANGES,DATETIME),
-	HTML_ATTR(CHANGES,DIR),
-	HTML_ATTR(CHANGES,ID),
-	HTML_ATTR(CHANGES,LANG),
-	HTML_ATTR(CHANGES,STYLE),
-	HTML_ATTR(CHANGES,TITLE),
-	HTML_ATTRIBUTES(CHANGES)
-};
-
-/*
-   (
-   FONT - Deprecated
-   )
-   */
-
-enum _HTML_FONT_Attributes {
-	HTML_ATTR(FONT,CLASS) = 0,
-	HTML_ATTR(FONT,COLOR),
-	HTML_ATTR(FONT,DIR),
-	HTML_ATTR(FONT,FACE),
-	HTML_ATTR(FONT,ID),
-	HTML_ATTR(FONT,LANG),
-	HTML_ATTR(FONT,SIZE),
-	HTML_ATTR(FONT,STYLE),
-	HTML_ATTR(FONT,TITLE),
-	HTML_ATTRIBUTES(FONT)
-};
-
-/*
-   (
-   FORM
-   )
-   */
-
-enum _HTML_FORM_Attributes {
-	HTML_ATTR(FORM,ACCEPT) = 0,
-	HTML_ATTR(FORM,ACCEPT_CHARSET), /* { "ACCEPT-CHARSET" } */
-	HTML_ATTR(FORM,ACTION),
-	HTML_ATTR(FORM,CLASS),
-	HTML_ATTR(FORM,DIR),
-	HTML_ATTR(FORM,ENCTYPE),
-	HTML_ATTR(FORM,ID),
-	HTML_ATTR(FORM,LANG),
-	HTML_ATTR(FORM,METHOD),
-	HTML_ATTR(FORM,STYLE),
-	HTML_ATTR(FORM,TARGET),
-	HTML_ATTR(FORM,TITLE),
-	HTML_ATTRIBUTES(FORM)
-};
-
-/*
-   (
-   FRAME
-   )
-   */
-
-enum _HTML_FRAME_Attributes {
-	HTML_ATTR(FRAME,CLASS) = 0,
-	HTML_ATTR(FRAME,FRAMEBORDER),
-	HTML_ATTR(FRAME,ID),
-	HTML_ATTR(FRAME,NAME),
-	HTML_ATTR(FRAME,MARGINHEIGHT),
-	HTML_ATTR(FRAME,MARGINWIDTH),
-	HTML_ATTR(FRAME,NORESIZE),
-	HTML_ATTR(FRAME,LONGDESC),
-	HTML_ATTR(FRAME,SCROLLING),
-	HTML_ATTR(FRAME,SRC),
-	HTML_ATTR(FRAME,STYLE),
-	HTML_ATTR(FRAME,TARGET),
-	HTML_ATTR(FRAME,TITLE),
-	HTML_ATTRIBUTES(FRAME)
-};
-
-/*
-   (
-   FRAMESET
-   )
-   */
-
-enum _HTML_FRAMESET_Attributes {
-	HTML_ATTR(FRAMESET,CLASS) = 0,
-	HTML_ATTR(FRAMESET,COLS),
-	HTML_ATTR(FRAMESET,ID),
-	HTML_ATTR(FRAMESET,ROWS),
-	HTML_ATTR(FRAMESET,STYLE),
-	HTML_ATTR(FRAMESET,TITLE),
-	HTML_ATTRIBUTES(FRAMESET)
-};
-
-/*
-   (
-   Generic attributes
-   )
-   */
-
-enum _HTML_GEN_Attributes {
-	HTML_ATTR(GEN,CLASS) = 0,
-	HTML_ATTR(GEN,DIR),
-	HTML_ATTR(GEN,ID),
-	HTML_ATTR(GEN,LANG),
-	HTML_ATTR(GEN,STYLE),
-	HTML_ATTR(GEN,TITLE),
-	HTML_ATTRIBUTES(GEN)
-};
-
-/*
-   (
-   BLOCK
-   )
-   */
-
-enum _HTML_BLOCK_Attributes {
-	HTML_ATTR(BLOCK,ALIGN) = 0,
-	HTML_ATTR(BLOCK,CLASS),
-	HTML_ATTR(BLOCK,DIR),
-	HTML_ATTR(BLOCK,ID),
-	HTML_ATTR(BLOCK,LANG),
-	HTML_ATTR(BLOCK,STYLE),
-	HTML_ATTR(BLOCK,TITLE),
-	HTML_ATTRIBUTES(BLOCK)
-};
-
-/*
-   (
-   HEAD
-   )
-   */
-
-enum _HTML_HEAD_Attributes {
-	HTML_ATTR(HEAD,DIR) = 0,
-	HTML_ATTR(HEAD,LANG),
-	HTML_ATTR(HEAD,PROFILE),
-	HTML_ATTRIBUTES(HEAD)
-};
-
-/*
-   (
-   HR
-   )
-   */
-
-enum _HTML_HR_Attributes {
-	HTML_ATTR(HR,ALIGN) = 0,
-	HTML_ATTR(HR,CLASS),
-	HTML_ATTR(HR,DIR),
-	HTML_ATTR(HR,ID),
-	HTML_ATTR(HR,LANG),
-	HTML_ATTR(HR,NOSHADE),
-	HTML_ATTR(HR,SIZE),
-	HTML_ATTR(HR,STYLE),
-	HTML_ATTR(HR,TITLE),
-	HTML_ATTR(HR,WIDTH),
-	HTML_ATTRIBUTES(HR)
-};
-
-/*
-   (
-   HTML
-   )
-   */
-
-enum _HTML_HTML_Attributes {
-	HTML_ATTR(HTML,DIR) = 0,
-	HTML_ATTR(HTML,LANG),
-	HTML_ATTR(HTML,VERSION),
-	HTML_ATTRIBUTES(HTML)
-};
-
-/*
-   (
-   IFRAME
-   )
-   */
-
-enum _HTML_IFRAME_Attributes {
-	HTML_ATTR(IFRAME,ALIGN) = 0,
-	HTML_ATTR(IFRAME,CLASS),
-	HTML_ATTR(IFRAME,FRAMEBORDER),
-	HTML_ATTR(IFRAME,HEIGHT),
-	HTML_ATTR(IFRAME,ID),
-	HTML_ATTR(IFRAME,LONGDESC),
-	HTML_ATTR(IFRAME,MARGINHEIGHT),
-	HTML_ATTR(IFRAME,MARGINWIDTH),
-	HTML_ATTR(IFRAME,NAME),
-	HTML_ATTR(IFRAME,SCROLLING),
-	HTML_ATTR(IFRAME,SRC),
-	HTML_ATTR(IFRAME,STYLE),
-	HTML_ATTR(IFRAME,TARGET),
-	HTML_ATTR(IFRAME,TITLE),
-	HTML_ATTR(IFRAME,WIDTH),
-	HTML_ATTRIBUTES(IFRAME)
-};
-
-/*
-   (
-   IMG
-   )
-   */
-
-enum _HTML_IMG_Attributes {
-	HTML_ATTR(IMG,ALIGN) = 0,
-	HTML_ATTR(IMG,ALT),
-	HTML_ATTR(IMG,BORDER),
-	HTML_ATTR(IMG,CLASS),
-	HTML_ATTR(IMG,DIR),
-	HTML_ATTR(IMG,HEIGHT),
-	HTML_ATTR(IMG,HSPACE),
-	HTML_ATTR(IMG,ID),
-	HTML_ATTR(IMG,ISMAP),
-	HTML_ATTR(IMG,LANG),
-	HTML_ATTR(IMG,LONGDESC),
-	HTML_ATTR(IMG,SRC),
-	HTML_ATTR(IMG,STYLE),
-	HTML_ATTR(IMG,TITLE),
-	HTML_ATTR(IMG,USEMAP),
-	HTML_ATTR(IMG,VSPACE),
-	HTML_ATTR(IMG,WIDTH),
-	HTML_ATTRIBUTES(IMG)
-};
-
-/*
-   (
-   INPUT
-   )
-   */
-
-enum _HTML_INPUT_Attributes {
-	HTML_ATTR(INPUT,ACCEPT) = 0,
-	HTML_ATTR(INPUT,ACCESSKEY),
-	HTML_ATTR(INPUT,ALIGN),
-	HTML_ATTR(INPUT,ALT),
-	HTML_ATTR(INPUT,CHECKED),
-	HTML_ATTR(INPUT,CLASS),
-	HTML_ATTR(INPUT,DIR),
-	HTML_ATTR(INPUT,DISABLED),
-	HTML_ATTR(INPUT,ID),
-	HTML_ATTR(INPUT,LANG),
-	HTML_ATTR(INPUT,MAXLENGTH),
-	HTML_ATTR(INPUT,NAME),
-	HTML_ATTR(INPUT,READONLY),
-	HTML_ATTR(INPUT,SIZE),
-	HTML_ATTR(INPUT,SRC),
-	HTML_ATTR(INPUT,STYLE),
-	HTML_ATTR(INPUT,TABINDEX),
-	HTML_ATTR(INPUT,TITLE),
-	HTML_ATTR(INPUT,TYPE),
-	HTML_ATTR(INPUT,USEMAP),
-	HTML_ATTR(INPUT,VALUE),
-	HTML_ATTRIBUTES(INPUT)
-};
-
-/*
-   (
-   )
-   */
-
-enum _HTML_ISINDEX_Attributes {
-	HTML_ATTR(ISINDEX,CLASS) = 0,
-	HTML_ATTR(ISINDEX,DIR),
-	HTML_ATTR(ISINDEX,ID),
-	HTML_ATTR(ISINDEX,LANG),
-	HTML_ATTR(ISINDEX,PROMPT),
-	HTML_ATTR(ISINDEX,STYLE),
-	HTML_ATTR(ISINDEX,TITLE),
-	HTML_ATTRIBUTES(ISINDEX)
-};
-
-/*
-   (
-   )
-   */
-
-enum _HTML_LABEL_Attributes {
-	HTML_ATTR(LABEL,ACCESSKEY) = 0,
-	HTML_ATTR(LABEL,CLASS),
-	HTML_ATTR(LABEL,DIR),
-	HTML_ATTR(LABEL,FOR),
-	HTML_ATTR(LABEL,ID),
-	HTML_ATTR(LABEL,LANG),
-	HTML_ATTR(LABEL,STYLE),
-	HTML_ATTR(LABEL,TITLE),
-	HTML_ATTRIBUTES(LABEL)
-};
-
-/*
-   (
-   )
-   */
-
-enum _HTML_LEGEND_Attributes {
-	HTML_ATTR(LEGEND,ACCESSKEY) = 0,
-	HTML_ATTR(LEGEND,ALIGN),
-	HTML_ATTR(LEGEND,CLASS),
-	HTML_ATTR(LEGEND,DIR),
-	HTML_ATTR(LEGEND,ID),
-	HTML_ATTR(LEGEND,LANG),
-	HTML_ATTR(LEGEND,STYLE),
-	HTML_ATTR(LEGEND,TITLE),
-	HTML_ATTRIBUTES(LEGEND)
-};
-
-/*
-   (
-   LI
-   )
-   */
-
-enum _HTML_LI_Attributes {
-	HTML_ATTR(LI,CLASS) = 0,
-	HTML_ATTR(LI,COMPACT),
-	HTML_ATTR(LI,DIR),
-	HTML_ATTR(LI,ID),
-	HTML_ATTR(LI,LANG),
-	HTML_ATTR(LI,STYLE),
-	HTML_ATTR(LI,TITLE),
-	HTML_ATTR(LI,TYPE),
-	HTML_ATTR(LI,VALUE),
-	HTML_ATTRIBUTES(LI)
-};
-
-/*
-   (
-   LINK
-   )
-   */
-
-enum _HTML_LINK_Attributes {
-	HTML_ATTR(LINK,CHARSET) = 0,
-	HTML_ATTR(LINK,CLASS),
-	HTML_ATTR(LINK,DIR),
-	HTML_ATTR(LINK,HREF),
-	HTML_ATTR(LINK,HREFLANG),
-	HTML_ATTR(LINK,ID),
-	HTML_ATTR(LINK,LANG),
-	HTML_ATTR(LINK,MEDIA),
-	HTML_ATTR(LINK,REL),
-	HTML_ATTR(LINK,REV),
-	HTML_ATTR(LINK,STYLE),
-	HTML_ATTR(LINK,TARGET),
-	HTML_ATTR(LINK,TITLE),
-	HTML_ATTR(LINK,TYPE),
-	HTML_ATTRIBUTES(LINK)
-};
-
-/*
-   (
-   MAP
-   )
-   */
-
-enum _HTML_MAP_Attributes {
-	HTML_ATTR(MAP,CLASS) = 0,
-	HTML_ATTR(MAP,DIR),
-	HTML_ATTR(MAP,ID),
-	HTML_ATTR(MAP,LANG),
-	HTML_ATTR(MAP,NAME),
-	HTML_ATTR(MAP,STYLE),
-	HTML_ATTR(MAP,TITLE),
-	HTML_ATTRIBUTES(MAP)
-};
-
-/*
-   (
-   META
-   )
-   */
-
-enum _HTML_META_Attributes {
-	HTML_ATTR(META,CONTENT) = 0,
-	HTML_ATTR(META,DIR),
-	HTML_ATTR(META,HTTP_EQUIV),    /* { "HTTP-EQUIV" ) */
-	HTML_ATTR(META,LANG),
-	HTML_ATTR(META,NAME),
-	HTML_ATTR(META,SCHEME),
-	HTML_ATTRIBUTES(META)
-};	
-
-/*
-   (
-   NEXTID
-   )
-   */
-
-#define HTML_NEXTID_ATTRIBUTES  1
-#define HTML_NEXTID_N 0
-
-/*
-   (
-   OBJECT
-   )
-   */
-
-enum _HTML_OBJECT_Attributes {
-	HTML_ATTR(OBJECT,ALIGN) = 0,
-	HTML_ATTR(OBJECT,ARCHIVE),
-	HTML_ATTR(OBJECT,BORDER),
-	HTML_ATTR(OBJECT,CLASS),
-	HTML_ATTR(OBJECT,CLASSID),
-	HTML_ATTR(OBJECT,CODEBASE),
-	HTML_ATTR(OBJECT,CODETYPE),
-	HTML_ATTR(OBJECT,DATA),
-	HTML_ATTR(OBJECT,DECLARE),
-	HTML_ATTR(OBJECT,DIR),
-	HTML_ATTR(OBJECT,HEIGHT),
-	HTML_ATTR(OBJECT,HSPACE),
-	HTML_ATTR(OBJECT,ID),
-	HTML_ATTR(OBJECT,LANG),
-	HTML_ATTR(OBJECT,NAME),
-	HTML_ATTR(OBJECT,STANDBY),
-	HTML_ATTR(OBJECT,STYLE),
-	HTML_ATTR(OBJECT,TABINDEX),
-	HTML_ATTR(OBJECT,TITLE),
-	HTML_ATTR(OBJECT,TYPE),
-	HTML_ATTR(OBJECT,USEMAP),
-	HTML_ATTR(OBJECT,VSPACE),
-	HTML_ATTR(OBJECT,WIDTH),
-	HTML_ATTRIBUTES(OBJECT)
-};
-
-/*
-   (
-   OL
-   )
-   */
-
-enum _HTML_OL_Attributes {
-	HTML_ATTR(OL,CLASS) = 0,
-	HTML_ATTR(OL,COMPACT),
-	HTML_ATTR(OL,DIR),
-	HTML_ATTR(OL,ID),
-	HTML_ATTR(OL,LANG),
-	HTML_ATTR(OL,START),
-	HTML_ATTR(OL,STYLE),
-	HTML_ATTR(OL,TITLE),
-	HTML_ATTR(OL,TYPE),
-	HTML_ATTRIBUTES(OL)
-};
-
-/*
-   (
-   OPTGROUP
-   )
-   */
-
-enum _HTML_OPTGROUP_Attributes {
-	HTML_ATTR(OPTGROUP,CLASS) = 0,
-	HTML_ATTR(OPTGROUP,DISABLED),
-	HTML_ATTR(OPTGROUP,DIR),
-	HTML_ATTR(OPTGROUP,ID),
-	HTML_ATTR(OPTGROUP,LABEL),
-	HTML_ATTR(OPTGROUP,LANG),
-	HTML_ATTR(OPTGROUP,STYLE),
-	HTML_ATTR(OPTGROUP,TITLE),
-	HTML_ATTRIBUTES(OPTGROUP)
-};
-
-/*
-   (
-   OPTION
-   )
-   */
-
-enum _HTML_OPTION_Attributes {
-	HTML_ATTR(OPTION,CLASS) = 0,
-	HTML_ATTR(OPTION,DISABLED),
-	HTML_ATTR(OPTION,DIR),
-	HTML_ATTR(OPTION,ID),
-	HTML_ATTR(OPTION,LABEL),
-	HTML_ATTR(OPTION,LANG),
-	HTML_ATTR(OPTION,SELECTED),
-	HTML_ATTR(OPTION,STYLE),
-	HTML_ATTR(OPTION,TITLE),
-	HTML_ATTR(OPTION,VALUE),
-	HTML_ATTRIBUTES(OPTION)
-};
-
-/*
-   (
-   PARAM
-   )
-   */
-
-enum _HTML_PARAM_Attributes {
-	HTML_ATTR(PARAM,ID) = 0,
-	HTML_ATTR(PARAM,NAME),
-	HTML_ATTR(PARAM,TYPE),
-	HTML_ATTR(PARAM,VALUE),
-	HTML_ATTR(PARAM,VALUETYPE),
-	HTML_ATTRIBUTES(PARAM)
-};
-
-/*
-   (
-   PRE
-   )
-   */
-
-enum _HTML_PRE_Attributes {
-	HTML_ATTR(PRE,CLASS) = 0,
-	HTML_ATTR(PRE,DIR),
-	HTML_ATTR(PRE,ID),
-	HTML_ATTR(PRE,LANG),
-	HTML_ATTR(PRE,STYLE),
-	HTML_ATTR(PRE,TITLE),
-	HTML_ATTR(PRE,WIDTH),
-	HTML_ATTRIBUTES(PRE)
-};
-
-/*
-   (
-   SCRIPT
-   )
-   */
-
-enum _HTML_SCRIPT_Attributes {
-	HTML_ATTR(SCRIPT,CHARSET) = 0,
-	HTML_ATTR(SCRIPT,DEFER),
-	HTML_ATTR(SCRIPT,LANGUAGE),
-	HTML_ATTR(SCRIPT,SRC),
-	HTML_ATTR(SCRIPT,TYPE),
-	HTML_ATTRIBUTES(SCRIPT)
-};
-
-/*
-   (
-   SELECT
-   )
-   */
-
-enum _HTML_SELECT_Attributes {
-	HTML_ATTR(SELECT,CLASS) = 0,
-	HTML_ATTR(SELECT,DIR),
-	HTML_ATTR(SELECT,DISABLED),
-	HTML_ATTR(SELECT,ID),
-	HTML_ATTR(SELECT,LANG),
-	HTML_ATTR(SELECT,MULTIPLE),
-	HTML_ATTR(SELECT,NAME),
-	HTML_ATTR(SELECT,SIZE),
-	HTML_ATTR(SELECT,STYLE),
-	HTML_ATTR(SELECT,TABINDEX),
-	HTML_ATTR(SELECT,TITLE),
-	HTML_ATTRIBUTES(SELECT)
-};
-
-/*
-   (
-   STYLE
-   )
-   */
-
-enum _HTML_STYLE_Attributes {
-	HTML_ATTR(STYLE,DIR) = 0,
-	HTML_ATTR(STYLE,LANG),
-	HTML_ATTR(STYLE,MEDIA),
-	HTML_ATTR(STYLE,TITLE),
-	HTML_ATTR(STYLE,TYPE),
-	HTML_ATTRIBUTES(STYLE)
-};
-
-/*
-   (
-   TABLE
-   )
-   */
-
-enum _HTML_TABLE_Attributes {
-	HTML_ATTR(TABLE,ALIGN) = 0,
-	HTML_ATTR(TABLE,BGCOLOR),
-	HTML_ATTR(TABLE,BORDER),
-	HTML_ATTR(TABLE,CELLPADDING),
-	HTML_ATTR(TABLE,CELLSPACING),
-	HTML_ATTR(TABLE,CLASS),
-	HTML_ATTR(TABLE,DIR),
-	HTML_ATTR(TABLE,FRAME),
-	HTML_ATTR(TABLE,ID),
-	HTML_ATTR(TABLE,LANG),
-	HTML_ATTR(TABLE,RULES),
-	HTML_ATTR(TABLE,SUMMARY),
-	HTML_ATTR(TABLE,STYLE),
-	HTML_ATTR(TABLE,TITLE),
-	HTML_ATTR(TABLE,WIDTH),
-	HTML_ATTRIBUTES(TABLE)
-};
-
-/*
-   (
-   TABLE Elements
-   )
-   */
-
-enum _HTML_TELE_Attributes {
-	HTML_ATTR(TELE,ALIGN) = 0,
-	HTML_ATTR(TELE,CHAR),
-	HTML_ATTR(TELE,CHAROFF),
-	HTML_ATTR(TELE,CLASS),
-	HTML_ATTR(TELE,DIR),
-	HTML_ATTR(TELE,ID),
-	HTML_ATTR(TELE,LANG),
-	HTML_ATTR(TELE,STYLE),
-	HTML_ATTR(TELE,TITLE),
-	HTML_ATTR(TELE,VALIGN),
-	HTML_ATTRIBUTES(TELE)
-};
-
-/*
-   (
-   TD
-   )
-   */
-
-enum _HTML_TD_Attributes {
-	HTML_ATTR(TD,ABBR) = 0,
-	HTML_ATTR(TD,ALIGN),
-	HTML_ATTR(TD,AXIS),
-	HTML_ATTR(TD,BGCOLOR),
-	HTML_ATTR(TD,CHAR),
-	HTML_ATTR(TD,CHAROFF),
-	HTML_ATTR(TD,CLASS),
-	HTML_ATTR(TD,COLSPAN),
-	HTML_ATTR(TD,DIR),
-	HTML_ATTR(TD,ID),
-	HTML_ATTR(TD,HEADERS),
-	HTML_ATTR(TD,HEIGHT),
-	HTML_ATTR(TD,LANG),
-	HTML_ATTR(TD,NOWRAP),
-	HTML_ATTR(TD,ROWSPAN),
-	HTML_ATTR(TD,SCOPE),
-	HTML_ATTR(TD,STYLE),
-	HTML_ATTR(TD,TITLE),
-	HTML_ATTR(TD,VALIGN),
-	HTML_ATTR(TD,WIDTH),
-	HTML_ATTRIBUTES(TD)
-};
-
-/*
-   (
-   TEXTAREA
-   )
-   */
-
-enum _HTML_TEXTAREA_Attributes {
-	HTML_ATTR(TEXTAREA,CLASS) = 0,
-	HTML_ATTR(TEXTAREA,COLS),
-	HTML_ATTR(TEXTAREA,DIR),
-	HTML_ATTR(TEXTAREA,DISABLED),
-	HTML_ATTR(TEXTAREA,ID),
-	HTML_ATTR(TEXTAREA,LANG),
-	HTML_ATTR(TEXTAREA,NAME),
-	HTML_ATTR(TEXTAREA,READONLY),
-	HTML_ATTR(TEXTAREA,ROWS),
-	HTML_ATTR(TEXTAREA,STYLE),
-	HTML_ATTR(TEXTAREA,TABINDEX),
-	HTML_ATTR(TEXTAREA,TITLE),
-	HTML_ATTRIBUTES(TEXTAREA)
-};
-
-/*
-   (
-   TITLE
-   )
-   */
-
-enum _HTML_TITLE_Attributes {
-	HTML_ATTR(TITLE,DIR) = 0,
-	HTML_ATTR(TITLE,LANG),
-	HTML_ATTRIBUTES(TITLE)
-};
-
-/*
-   (
-   UL
-   )
-   */
-
-enum _HTML_UL_Attributes {
-	HTML_ATTR(UL,CLASS) = 0,
-	HTML_ATTR(UL,COMPACT),
-	HTML_ATTR(UL,DIR),
-	HTML_ATTR(UL,ID),
-	HTML_ATTR(UL,LANG),
-	HTML_ATTR(UL,STYLE),
-	HTML_ATTR(UL,TITLE),
-	HTML_ATTR(UL,TYPE),
-	HTML_ATTRIBUTES(UL)
-};
-
-
-/*
-**	ELEMENTS
-**	Must match definitions in HTMLPDTD.html!
-**	Must be in alphabetical order.
-**
-**    Name, 	Attributes, 		content
-*/
-
-//
-// SGML.h
-//
-#define MAX_ATTRIBUTES 32
-
-typedef struct _HTAttr {
-	char * name;
-} HTAttr;
-
-// striped struct
-typedef struct _HTTag {
-	std::string name;
-	HTAttr * attributes;
-	int number_of_attributes;
-} HTTag;
-
-// entities are removed
-typedef struct {
-	HTTag * tags;
-	int number_of_tags;
-} SGML_dtd;
-
-SGML_dtd * HTML_dtd (void);
-
-#endif
-
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 218ff06cf..6605fa591 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -1444,7 +1444,6 @@ namespace NLGUI
 
 		initImageDownload();
 		initBnpDownload();
-		initLibWWW();
 	}
 
 	// ***************************************************************************
diff --git a/code/nel/src/gui/html_parser.cpp b/code/nel/src/gui/html_parser.cpp
index d411b856e..1c5914bb5 100644
--- a/code/nel/src/gui/html_parser.cpp
+++ b/code/nel/src/gui/html_parser.cpp
@@ -59,8 +59,6 @@ namespace NLGUI
 	// recursive function to walk html document
 	void CHtmlParser::parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const
 	{
-		SGML_dtd *HTML_DTD = HTML_dtd ();
-
 		uint childIndex = 0;
 		uint element_number;
 		xmlNode *node = a_node;
@@ -73,12 +71,8 @@ namespace NLGUI
 			else
 			if (node->type == XML_ELEMENT_NODE)
 			{
-				// find libwww tag
-				for(element_number = 0; element_number<HTML_ELEMENTS; ++element_number)
-				{
-					if (xmlStrncasecmp(node->name, (const xmlChar *)HTML_DTD->tags[element_number].name.c_str(), xmlStrlen(node->name)) == 0)
-						break;
-				}
+				// find html element
+				element_number = htmlElementLookup((const char*)node->name);
 
 				// get pointer to previous sibling
 				CHtmlElement *prevSibling = NULL;
diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp
index 0ee6c01f2..56e7f0c71 100644
--- a/code/nel/src/gui/libwww.cpp
+++ b/code/nel/src/gui/libwww.cpp
@@ -29,6 +29,167 @@ using namespace NLMISC;
 
 namespace NLGUI
 {
+	struct CNameToHtmlElement
+	{
+		HTMLElement ID;
+		const char* Name;
+		CNameToHtmlElement(HTMLElement id, const char*name)
+			: ID(id), Name(name) {}
+	};
+
+	// sorted list of HTML_ELEMENT enum to TAG name
+	static CNameToHtmlElement htmlElementToName[] =
+	{
+		CNameToHtmlElement(HTML_A, "a"),
+		CNameToHtmlElement(HTML_ABBR, "abbr"),
+		CNameToHtmlElement(HTML_ADDRESS, "address"),
+		CNameToHtmlElement(HTML_APPLET, "applet"),
+		CNameToHtmlElement(HTML_AREA, "area"),
+		CNameToHtmlElement(HTML_ARTICLE, "article"),
+		CNameToHtmlElement(HTML_ASIDE, "aside"),
+		CNameToHtmlElement(HTML_AUDIO, "audio"),
+		CNameToHtmlElement(HTML_B, "b"),
+		CNameToHtmlElement(HTML_BASE, "base"),
+		CNameToHtmlElement(HTML_BDI, "bdi"),
+		CNameToHtmlElement(HTML_BDO, "bdo"),
+		CNameToHtmlElement(HTML_BLOCKQUOTE, "blockquote"),
+		CNameToHtmlElement(HTML_BODY, "body"),
+		CNameToHtmlElement(HTML_BR, "br"),
+		CNameToHtmlElement(HTML_BUTTON, "button"),
+		CNameToHtmlElement(HTML_CANVAS, "canvas"),
+		CNameToHtmlElement(HTML_CAPTION, "caption"),
+		CNameToHtmlElement(HTML_CITE, "cite"),
+		CNameToHtmlElement(HTML_CODE, "code"),
+		CNameToHtmlElement(HTML_COL, "col"),
+		CNameToHtmlElement(HTML_COLGROUP, "colgroup"),
+		CNameToHtmlElement(HTML_DATA, "data"),
+		CNameToHtmlElement(HTML_DATALIST, "datalist"),
+		CNameToHtmlElement(HTML_DD, "dd"),
+		CNameToHtmlElement(HTML_DEL, "del"),
+		CNameToHtmlElement(HTML_DETAILS, "details"),
+		CNameToHtmlElement(HTML_DFN, "dfn"),
+		CNameToHtmlElement(HTML_DIALOG, "dialog"),
+		CNameToHtmlElement(HTML_DIR, "dir"),
+		CNameToHtmlElement(HTML_DIV, "div"),
+		CNameToHtmlElement(HTML_DL, "dl"),
+		CNameToHtmlElement(HTML_DT, "dt"),
+		CNameToHtmlElement(HTML_EM, "em"),
+		CNameToHtmlElement(HTML_EMBED, "embed"),
+		CNameToHtmlElement(HTML_FIELDSET, "fieldset"),
+		CNameToHtmlElement(HTML_FIGCAPTION, "figcaption"),
+		CNameToHtmlElement(HTML_FIGURE, "figure"),
+		CNameToHtmlElement(HTML_FONT, "font"),
+		CNameToHtmlElement(HTML_FOOTER, "footer"),
+		CNameToHtmlElement(HTML_FORM, "form"),
+		CNameToHtmlElement(HTML_H1, "h1"),
+		CNameToHtmlElement(HTML_H2, "h2"),
+		CNameToHtmlElement(HTML_H3, "h3"),
+		CNameToHtmlElement(HTML_H4, "h4"),
+		CNameToHtmlElement(HTML_H5, "h5"),
+		CNameToHtmlElement(HTML_H6, "h6"),
+		CNameToHtmlElement(HTML_HEAD, "head"),
+		CNameToHtmlElement(HTML_HEADER, "header"),
+		CNameToHtmlElement(HTML_HGROUP, "hgroup"),
+		CNameToHtmlElement(HTML_HR, "hr"),
+		CNameToHtmlElement(HTML_HTML, "html"),
+		CNameToHtmlElement(HTML_I, "i"),
+		CNameToHtmlElement(HTML_IFRAME, "iframe"),
+		CNameToHtmlElement(HTML_IMG, "img"),
+		CNameToHtmlElement(HTML_INPUT, "input"),
+		CNameToHtmlElement(HTML_INS, "ins"),
+		CNameToHtmlElement(HTML_KBD, "kbd"),
+		CNameToHtmlElement(HTML_LABEL, "label"),
+		CNameToHtmlElement(HTML_LEGEND, "legend"),
+		CNameToHtmlElement(HTML_LI, "li"),
+		CNameToHtmlElement(HTML_LINK, "link"),
+		CNameToHtmlElement(HTML_LUA, "lua"),
+		CNameToHtmlElement(HTML_MAIN, "main"),
+		CNameToHtmlElement(HTML_MAP, "map"),
+		CNameToHtmlElement(HTML_MARK, "mark"),
+		CNameToHtmlElement(HTML_MENU, "menu"),
+		CNameToHtmlElement(HTML_MENUITEM, "menuitem"),
+		CNameToHtmlElement(HTML_META, "meta"),
+		CNameToHtmlElement(HTML_METER, "meter"),
+		CNameToHtmlElement(HTML_NAV, "nav"),
+		CNameToHtmlElement(HTML_NOEMBED, "noembed"),
+		CNameToHtmlElement(HTML_NOSCRIPT, "noscript"),
+		CNameToHtmlElement(HTML_OBJECT, "object"),
+		CNameToHtmlElement(HTML_OL, "ol"),
+		CNameToHtmlElement(HTML_OPTGROUP, "optgroup"),
+		CNameToHtmlElement(HTML_OPTION, "option"),
+		CNameToHtmlElement(HTML_OUTPUT, "output"),
+		CNameToHtmlElement(HTML_P, "p"),
+		CNameToHtmlElement(HTML_PARAM, "param"),
+		CNameToHtmlElement(HTML_PICTURE, "picture"),
+		CNameToHtmlElement(HTML_PRE, "pre"),
+		CNameToHtmlElement(HTML_PROGRESS, "progress"),
+		CNameToHtmlElement(HTML_Q, "q"),
+		CNameToHtmlElement(HTML_RB, "rb"),
+		CNameToHtmlElement(HTML_RP, "rp"),
+		CNameToHtmlElement(HTML_RT, "rt"),
+		CNameToHtmlElement(HTML_RTC, "rtc"),
+		CNameToHtmlElement(HTML_RUBY, "ruby"),
+		CNameToHtmlElement(HTML_S, "s"),
+		CNameToHtmlElement(HTML_SAMP, "samp"),
+		CNameToHtmlElement(HTML_SCRIPT, "script"),
+		CNameToHtmlElement(HTML_SECTION, "section"),
+		CNameToHtmlElement(HTML_SELECT, "select"),
+		CNameToHtmlElement(HTML_SMALL, "small"),
+		CNameToHtmlElement(HTML_SOURCE, "source"),
+		CNameToHtmlElement(HTML_SPAN, "span"),
+		CNameToHtmlElement(HTML_STRONG, "strong"),
+		CNameToHtmlElement(HTML_STYLE, "style"),
+		CNameToHtmlElement(HTML_SUB, "sub"),
+		CNameToHtmlElement(HTML_SUMMARY, "summary"),
+		CNameToHtmlElement(HTML_SUP, "sup"),
+		CNameToHtmlElement(HTML_TABLE, "table"),
+		CNameToHtmlElement(HTML_TBODY, "tbody"),
+		CNameToHtmlElement(HTML_TD, "td"),
+		CNameToHtmlElement(HTML_TEXTAREA, "textarea"),
+		CNameToHtmlElement(HTML_TFOOT, "tfoot"),
+		CNameToHtmlElement(HTML_TH, "th"),
+		CNameToHtmlElement(HTML_THEAD, "thead"),
+		CNameToHtmlElement(HTML_TIME, "time"),
+		CNameToHtmlElement(HTML_TITLE, "title"),
+		CNameToHtmlElement(HTML_TR, "tr"),
+		CNameToHtmlElement(HTML_TRACK, "track"),
+		CNameToHtmlElement(HTML_TT, "tt"),
+		CNameToHtmlElement(HTML_U, "u"),
+		CNameToHtmlElement(HTML_UL, "ul"),
+		CNameToHtmlElement(HTML_VAR, "var"),
+		CNameToHtmlElement(HTML_VIDEO, "video"),
+		CNameToHtmlElement(HTML_WBR, "wbr")
+	};
+
+	HTMLElement htmlElementLookup(const char* name)
+	{
+		uint end = sizeofarray(htmlElementToName);
+		uint mid = end >> 1;
+		sint ret;
+		while(mid < end)
+		{
+			sint ret = nlstricmp(name, htmlElementToName[mid].Name);
+			if (ret == 0)
+			{
+				return htmlElementToName[mid].ID;
+			}
+			else if (ret < 0)
+			{
+				// lower half
+				end = mid;
+				mid = end >> 1;
+			}
+			else
+			{
+				// upper half
+				mid++;
+				mid += (end - mid) >> 1;
+			}
+		}
+
+		// not found
+		return HTML_NB_ELEMENTS;
+	}
 
 	// ***************************************************************************
 
@@ -40,258 +201,6 @@ namespace NLGUI
 
 	// ***************************************************************************
 
-	// Some DTD table
-
-	// Here, modify the DTD table to change the HTML parser (add new tags for examples)
-
-	#undef HTML_ATTR
-	#define HTML_ATTR(a,b) { (char*) #b }
-
-	HTAttr html_attr[] =
-	{
-		HTML_ATTR(HTML,DIR),
-		HTML_ATTR(HTML,LANG),
-		HTML_ATTR(HTML,VERSION),
-		HTML_ATTR(HTML,STYLE),
-		{ 0 }
-	};
-
-	HTAttr a_attr[] =
-	{
-		HTML_ATTR(A,ACCESSKEY),
-			HTML_ATTR(A,CHARSET),
-			HTML_ATTR(A,CLASS),
-			HTML_ATTR(A,COORDS),
-			HTML_ATTR(A,DIR),
-			HTML_ATTR(A,HREF),
-			HTML_ATTR(A,HREFLANG),
-			HTML_ATTR(A,ID),
-			HTML_ATTR(A,NAME),
-			HTML_ATTR(A,REL),
-			HTML_ATTR(A,REV),
-			HTML_ATTR(A,SHAPE),
-			HTML_ATTR(A,STYLE),
-			HTML_ATTR(A,TABINDEX),
-			HTML_ATTR(A,TARGET),
-			HTML_ATTR(A,TYPE),
-			HTML_ATTR(A,TITLE),
-			HTML_ATTR(A,Z_ACTION_CATEGORY),
-			HTML_ATTR(A,Z_ACTION_PARAMS),
-			HTML_ATTR(A,Z_ACTION_SHORTCUT),
-		{ 0 }
-	};
-
-	HTAttr table_attr[] =
-	{
-		HTML_ATTR(TABLE,ALIGN),
-			HTML_ATTR(TABLE,BGCOLOR),
-			HTML_ATTR(TABLE,BORDER),
-			HTML_ATTR(TABLE,BORDERCOLOR),
-			HTML_ATTR(TABLE,CELLPADDING),
-			HTML_ATTR(TABLE,CELLSPACING),
-			HTML_ATTR(TABLE,CLASS),
-			HTML_ATTR(TABLE,DIR),
-			HTML_ATTR(TABLE,FRAME),
-			HTML_ATTR(TABLE,ID),
-			HTML_ATTR(TABLE,L_MARGIN),
-			HTML_ATTR(TABLE,LANG),
-			HTML_ATTR(TABLE,NOWRAP),
-			HTML_ATTR(TABLE,RULES),
-			HTML_ATTR(TABLE,SUMMARY),
-			HTML_ATTR(TABLE,STYLE),
-			HTML_ATTR(TABLE,TITLE),
-			HTML_ATTR(TABLE,VALIGN),
-			HTML_ATTR(TABLE,WIDTH),
-		{ 0 }
-	};
-
-	HTAttr tr_attr[] =
-	{
-		HTML_ATTR(TR,ALIGN),
-			HTML_ATTR(TR,BGCOLOR),
-			HTML_ATTR(TR,L_MARGIN),
-			HTML_ATTR(TR,NOWRAP),
-			HTML_ATTR(TR,VALIGN),
-			HTML_ATTR(TR,STYLE),
-		{ 0 }
-	};
-
-	HTAttr td_attr[] =
-	{
-		HTML_ATTR(TD,ABBR),
-			HTML_ATTR(TD,ALIGN),
-			HTML_ATTR(TD,AXIS),
-			HTML_ATTR(TD,BGCOLOR),
-			HTML_ATTR(TD,CHAR),
-			HTML_ATTR(TD,CHAROFF),
-			HTML_ATTR(TD,CLASS),
-			HTML_ATTR(TD,COLSPAN),
-			HTML_ATTR(TD,DIR),
-			HTML_ATTR(TD,ID),
-			HTML_ATTR(TD,HEADERS),
-			HTML_ATTR(TD,HEIGHT),
-			HTML_ATTR(TD,L_MARGIN),
-			HTML_ATTR(TD,LANG),
-			HTML_ATTR(TD,NOWRAP),
-			HTML_ATTR(TD,ROWSPAN),
-			HTML_ATTR(TD,SCOPE),
-			HTML_ATTR(TD,STYLE),
-			HTML_ATTR(TD,TITLE),
-			HTML_ATTR(TD,VALIGN),
-			HTML_ATTR(TD,WIDTH),
-		{ 0 }
-	};
-
-	HTAttr img_attr[] =
-	{
-		HTML_ATTR(IMG,ALIGN),
-			HTML_ATTR(IMG,ALT),
-			HTML_ATTR(IMG,BORDER),
-			HTML_ATTR(IMG,CLASS),
-			HTML_ATTR(IMG,DIR),
-			HTML_ATTR(IMG,GLOBAL_COLOR),
-			HTML_ATTR(IMG,HEIGHT),
-			HTML_ATTR(IMG,HSPACE),
-			HTML_ATTR(IMG,ID),
-			HTML_ATTR(IMG,ISMAP),
-			HTML_ATTR(IMG,LANG),
-			HTML_ATTR(IMG,LONGDESC),
-			HTML_ATTR(IMG,SRC),
-			HTML_ATTR(IMG,STYLE),
-			HTML_ATTR(IMG,TITLE),
-			HTML_ATTR(IMG,USEMAP),
-			HTML_ATTR(IMG,VSPACE),
-			HTML_ATTR(IMG,WIDTH),
-			// not sorted to keep enum values
-			HTML_ATTR(IMG,DATA-OVER-SRC),
-			{ 0 }
-	};
-
-	HTAttr input_attr[] =
-	{
-		HTML_ATTR(INPUT,ACCEPT),
-			HTML_ATTR(INPUT,ACCESSKEY),
-			HTML_ATTR(INPUT,ALIGN),
-			HTML_ATTR(INPUT,ALT),
-			HTML_ATTR(INPUT,CHECKED),
-			HTML_ATTR(INPUT,CLASS),
-			HTML_ATTR(INPUT,DIR),
-			HTML_ATTR(INPUT,DISABLED),
-			HTML_ATTR(INPUT,GLOBAL_COLOR),
-			HTML_ATTR(INPUT,ID),
-			HTML_ATTR(INPUT,LANG),
-			HTML_ATTR(INPUT,MAXLENGTH),
-			HTML_ATTR(INPUT,NAME),
-			HTML_ATTR(INPUT,READONLY),
-			HTML_ATTR(INPUT,SIZE),
-			HTML_ATTR(INPUT,SRC),
-			HTML_ATTR(INPUT,STYLE),
-			HTML_ATTR(INPUT,TABINDEX),
-			HTML_ATTR(INPUT,TITLE),
-			HTML_ATTR(INPUT,TYPE),
-			HTML_ATTR(INPUT,USEMAP),
-			HTML_ATTR(INPUT,VALUE),
-			HTML_ATTR(INPUT,Z_BTN_TMPL),
-			HTML_ATTR(INPUT,Z_INPUT_TMPL),
-			HTML_ATTR(INPUT,Z_INPUT_WIDTH),
-		{ 0 }
-	};
-
-	HTAttr textarea_attr[] =
-	{
-		HTML_ATTR(TEXTAREA,CLASS),
-		HTML_ATTR(TEXTAREA,COLS),
-		HTML_ATTR(TEXTAREA,DIR),
-		HTML_ATTR(TEXTAREA,DISABLED),
-		HTML_ATTR(TEXTAREA,ID),
-		HTML_ATTR(TEXTAREA,LANG),
-		HTML_ATTR(TEXTAREA,MAXLENGTH),
-		HTML_ATTR(TEXTAREA,NAME),
-		HTML_ATTR(TEXTAREA,READONLY),
-		HTML_ATTR(TEXTAREA,ROWS),
-		HTML_ATTR(TEXTAREA,STYLE),
-		HTML_ATTR(TEXTAREA,TABINDEX),
-		HTML_ATTR(TEXTAREA,TITLE),
-		HTML_ATTR(TEXTAREA,Z_INPUT_TMPL),
-		{ 0 }
-	};
-
-	HTAttr p_attr[] =
-	{
-		HTML_ATTR(P,QUICK_HELP_CONDITION),
-			HTML_ATTR(P,QUICK_HELP_EVENTS),
-			HTML_ATTR(P,QUICK_HELP_LINK),
-			HTML_ATTR(P,NAME),
-			HTML_ATTR(P,STYLE),
-		{ 0 }
-	};
-
-
-	HTAttr div_attr[] =
-	{
-		HTML_ATTR(DIV,CLASS),
-			HTML_ATTR(DIV,ID),
-			HTML_ATTR(DIV,NAME),
-			HTML_ATTR(DIV,STYLE),
-		{ 0 }
-	};
-
-	HTAttr span_attr[] =
-	{
-		HTML_ATTR(SPAN,CLASS),
-		HTML_ATTR(SPAN,ID),
-		HTML_ATTR(SPAN,STYLE),
-		{ 0 }
-	};
-
-	HTAttr h1_attr[] =
-	{
-		HTML_ATTR(H1,CLASS),
-		HTML_ATTR(H1,ID),
-		HTML_ATTR(H1,STYLE),
-		{ 0 }
-	};
-
-	HTAttr h2_attr[] =
-	{
-		HTML_ATTR(H2,CLASS),
-		HTML_ATTR(H2,ID),
-		HTML_ATTR(H2,STYLE),
-		{ 0 }
-	};
-
-	HTAttr h3_attr[] =
-	{
-		HTML_ATTR(H3,CLASS),
-		HTML_ATTR(H3,ID),
-		HTML_ATTR(H3,STYLE),
-		{ 0 }
-	};
-
-	HTAttr h4_attr[] =
-	{
-		HTML_ATTR(H4,CLASS),
-		HTML_ATTR(H4,ID),
-		HTML_ATTR(H4,STYLE),
-		{ 0 }
-	};
-
-	HTAttr h5_attr[] =
-	{
-		HTML_ATTR(H5,CLASS),
-		HTML_ATTR(H5,ID),
-		HTML_ATTR(H5,STYLE),
-		{ 0 }
-	};
-
-	HTAttr h6_attr[] =
-	{
-		HTML_ATTR(H6,CLASS),
-		HTML_ATTR(H6,ID),
-		HTML_ATTR(H6,STYLE),
-		{ 0 }
-	};
-
 	// ***************************************************************************
 	bool getCssLength (float &value, std::string &unit, const std::string &str)
 	{
@@ -873,58 +782,6 @@ namespace NLGUI
 		}
 	}
 
-	void initLibWWW()
-	{
-		static bool initialized = false;
-		if (!initialized)
-		{
-
-			// Change the HTML DTD
-			SGML_dtd *HTML_DTD = HTML_dtd ();
-			HTML_DTD->tags[HTML_HTML].attributes = html_attr;
-			HTML_DTD->tags[HTML_HTML].number_of_attributes = sizeof(html_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_TABLE].attributes = table_attr;
-			HTML_DTD->tags[HTML_TABLE].number_of_attributes = sizeof(table_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_TR].attributes = tr_attr;
-			HTML_DTD->tags[HTML_TR].number_of_attributes = sizeof(tr_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_TD].attributes = td_attr;
-			HTML_DTD->tags[HTML_TD].number_of_attributes = sizeof(td_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_TH].attributes = td_attr;
-			HTML_DTD->tags[HTML_TH].number_of_attributes = sizeof(td_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_IMG].attributes = img_attr;
-			HTML_DTD->tags[HTML_IMG].number_of_attributes = sizeof(img_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_INPUT].attributes = input_attr;
-			HTML_DTD->tags[HTML_INPUT].number_of_attributes = sizeof(input_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_TEXTAREA].attributes = textarea_attr;
-			HTML_DTD->tags[HTML_TEXTAREA].number_of_attributes = sizeof(textarea_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_P].attributes = p_attr;
-			HTML_DTD->tags[HTML_P].number_of_attributes = sizeof(p_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_A].attributes = a_attr;
-			HTML_DTD->tags[HTML_A].number_of_attributes = sizeof(a_attr) / sizeof(HTAttr) - 1;
-			//HTML_DTD->tags[HTML_I].attributes = a_attr;
-			HTML_DTD->tags[HTML_I].number_of_attributes = 0;
-			HTML_DTD->tags[HTML_DIV].attributes = div_attr;
-			HTML_DTD->tags[HTML_DIV].number_of_attributes = sizeof(div_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_SPAN].attributes = span_attr;
-			HTML_DTD->tags[HTML_SPAN].number_of_attributes = sizeof(span_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_H1].attributes = h1_attr;
-			HTML_DTD->tags[HTML_H1].number_of_attributes = sizeof(h1_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_H2].attributes = h2_attr;
-			HTML_DTD->tags[HTML_H2].number_of_attributes = sizeof(h2_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_H3].attributes = h3_attr;
-			HTML_DTD->tags[HTML_H3].number_of_attributes = sizeof(h3_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_H4].attributes = h4_attr;
-			HTML_DTD->tags[HTML_H4].number_of_attributes = sizeof(h4_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_H5].attributes = h5_attr;
-			HTML_DTD->tags[HTML_H5].number_of_attributes = sizeof(h5_attr) / sizeof(HTAttr) - 1;
-			HTML_DTD->tags[HTML_H6].attributes = h6_attr;
-			HTML_DTD->tags[HTML_H6].number_of_attributes = sizeof(h6_attr) / sizeof(HTAttr) - 1;
-
-			// Initialized
-			initialized = true;
-		}
-	}
-
 	// ***************************************************************************
 }
 
diff --git a/code/nel/src/gui/libwww_types.cpp b/code/nel/src/gui/libwww_types.cpp
deleted file mode 100644
index 12a16e5d6..000000000
--- a/code/nel/src/gui/libwww_types.cpp
+++ /dev/null
@@ -1,804 +0,0 @@
-/**
-                                                        libwww Copyright Notice
-   [This notice should be placed within redistributed or derivative software
-   code when appropriate. This particular formulation of W3C's notice for
-   inclusion in libwww code became active on August 14 1998.]
-
-                            LIBWWW COPYRIGHT NOTICE
-
-   libwww: W3C's implementation of HTTP can be found at:
-   http://www.w3.org/Library/
-
-                         Copyright ¨ 1995-2002 World Wide Web Consortium,
-                         (Massachusetts Institute of Technology, Institut
-                         National de Recherche en Informatique et en
-                         Automatique, Keio University). All Rights Reserved.
-                         This program is distributed under the W3C's
-                         Intellectual Property License. This program is
-                         distributed in the hope that it will be useful, but
-                         WITHOUT ANY WARRANTY; without even the implied
-                         warranty of MERCHANTABILITY or FITNESS FOR A
-                         PARTICULAR PURPOSE. See W3C License
-                         http://www.w3.org/Consortium/Legal/ for more details.
-
-                         Copyright ¨ 1995 CERN. "This product includes computer
-                         software created and made available by CERN. This
-                         acknowledgment shall be mentioned in full in any
-                         product which includes the CERN computer software
-                         included herein or parts thereof."
-
- ****************************************************************************/
-
-#include "stdpch.h"
-#include "nel/gui/libwww_types.h"
-
-#ifdef DEBUG_NEW
-#define new DEBUG_NEW
-#endif
-
-namespace NLGUI
-{
-
-/*
- **	ATTRIBUTE DEFINITION MACROS (see HTMLPDTD.h)
- */
-
-/*
- * redefine the macros, so that the "stringized" attribute name
- * is generated
- */
-
-#undef	HTML_ATTR
-#define	HTML_ATTR(t,a)		{ (char *) #a }
-#undef	HTML_ATTRIBUTES
-#define	HTML_ATTRIBUTES(t)	{ 0 }
-
-/*
- **	ATTRIBUTE LISTS
- */
-
-static HTAttr no_attr[1] = {
-	{ 0 }
-};
-
-static HTAttr body_attr[HTML_BODY_ATTRIBUTES+1] = {	/* to catch images */
-	HTML_ATTR(BODY,ALINK),
-	HTML_ATTR(BODY,BACKGROUND),
-	HTML_ATTR(BODY,BGCOLOR),
-	HTML_ATTR(BODY,CLASS),
-	HTML_ATTR(BODY,DIR),
-	HTML_ATTR(BODY,ID),
-	HTML_ATTR(BODY,LANG),
-	HTML_ATTR(BODY,LINK),
-	HTML_ATTR(BODY,STYLE),
-	HTML_ATTR(BODY,TEXT),
-	HTML_ATTR(BODY,TITLE),
-	HTML_ATTR(BODY,VLINK),
-	HTML_ATTRIBUTES(BODY)
-};
-
-static HTAttr frame_attr[HTML_FRAME_ATTRIBUTES+1] = {	/* frame attributes */
-	HTML_ATTR(FRAME,CLASS),
-	HTML_ATTR(FRAME,FRAMEBORDER),
-	HTML_ATTR(FRAME,ID),
-	HTML_ATTR(FRAME,NAME),
-	HTML_ATTR(FRAME,MARGINHEIGHT),
-	HTML_ATTR(FRAME,MARGINWIDTH),
-	HTML_ATTR(FRAME,NORESIZE),
-	HTML_ATTR(FRAME,LONGDESC),
-	HTML_ATTR(FRAME,SCROLLING),
-	HTML_ATTR(FRAME,SRC),
-	HTML_ATTR(FRAME,STYLE),
-	HTML_ATTR(FRAME,TARGET),
-	HTML_ATTR(FRAME,TITLE),
-	HTML_ATTRIBUTES(FRAME)
-};
-
-static HTAttr frameset_attr[HTML_FRAMESET_ATTRIBUTES+1] = { /* frameset attributes */
-	HTML_ATTR(FRAMESET,CLASS),
-	HTML_ATTR(FRAMESET,COLS),
-	HTML_ATTR(FRAMESET,ID),
-	HTML_ATTR(FRAMESET,ROWS),
-	HTML_ATTR(FRAMESET,STYLE),
-	HTML_ATTR(FRAMESET,TITLE),
-	HTML_ATTRIBUTES(FRAMESET)
-};
-
-static HTAttr a_attr[HTML_A_ATTRIBUTES+1] = {		/* Anchor attributes */
-	HTML_ATTR(A,ACCESSKEY),
-	HTML_ATTR(A,CHARSET),
-	HTML_ATTR(A,CLASS),
-	HTML_ATTR(A,COORDS),
-	HTML_ATTR(A,DIR),
-	HTML_ATTR(A,HREF),
-	HTML_ATTR(A,HREFLANG),
-	HTML_ATTR(A,ID),
-	HTML_ATTR(A,NAME),
-	HTML_ATTR(A,REL),
-	HTML_ATTR(A,REV),
-	HTML_ATTR(A,SHAPE),
-	HTML_ATTR(A,STYLE),
-	HTML_ATTR(A,TABINDEX),
-	HTML_ATTR(A,TARGET),
-	HTML_ATTR(A,TYPE),
-	HTML_ATTR(A,TITLE),
-	HTML_ATTRIBUTES(A)
-};
-
-static HTAttr applet_attr[HTML_APPLET_ATTRIBUTES+1] = {
-	HTML_ATTR(APPLET,ALIGN),
-	HTML_ATTR(APPLET,ALT),
-	HTML_ATTR(APPLET,ARCHIVE),
-	HTML_ATTR(APPLET,CLASS),
-	HTML_ATTR(APPLET,CODE),
-	HTML_ATTR(APPLET,CODEBASE),
-	HTML_ATTR(APPLET,HEIGHT),
-	HTML_ATTR(APPLET,HSPACE),
-	HTML_ATTR(APPLET,ID),
-	HTML_ATTR(APPLET,NAME),
-	HTML_ATTR(APPLET,OBJECT),
-	HTML_ATTR(APPLET,STYLE),
-	HTML_ATTR(APPLET,TITLE),
-	HTML_ATTR(APPLET,VSPACE),
-	HTML_ATTR(APPLET,WIDTH),
-	HTML_ATTRIBUTES(APPLET)
-};
-
-static HTAttr area_attr[HTML_AREA_ATTRIBUTES+1] = {		/* Area attributes */
-	HTML_ATTR(AREA,ACCESSKEY),
-	HTML_ATTR(AREA,ALT),
-	HTML_ATTR(AREA,CLASS),
-	HTML_ATTR(AREA,COORDS),
-	HTML_ATTR(AREA,DIR),
-	HTML_ATTR(AREA,HREF),
-	HTML_ATTR(AREA,ID),
-	HTML_ATTR(AREA,NAME),
-	HTML_ATTR(AREA,NOHREF),
-	HTML_ATTR(AREA,LANG),
-	HTML_ATTR(AREA,SHAPE),
-	HTML_ATTR(AREA,STYLE),
-	HTML_ATTR(AREA,TABINDEX),
-	HTML_ATTR(AREA,TARGET),
-	HTML_ATTR(AREA,TITLE),
-	HTML_ATTRIBUTES(AREA)
-};
-
-static HTAttr base_attr[HTML_BASE_ATTRIBUTES+1] = {	/* BASE attributes */
-	HTML_ATTR(BASE,HREF),
-	HTML_ATTR(BASE,TARGET),
-	HTML_ATTRIBUTES(BASE)
-};
-
-static HTAttr bdo_attr[HTML_BDO_ATTRIBUTES+1] = {
-	HTML_ATTR(BDO,CLASS),
-	HTML_ATTR(BDO,DIR),
-	HTML_ATTR(BDO,ID),
-	HTML_ATTR(BDO,LANG),
-	HTML_ATTR(BDO,STYLE),
-	HTML_ATTR(BDO,TITLE),
-	HTML_ATTRIBUTES(BDO)
-};
-
-static HTAttr bq_attr[HTML_BQ_ATTRIBUTES+1] = {
-	HTML_ATTR(BQ,CITE),
-	HTML_ATTR(BQ,CLASS),
-	HTML_ATTR(BQ,DIR),
-	HTML_ATTR(BQ,ID),
-	HTML_ATTR(BQ,LANG),
-	HTML_ATTR(BQ,STYLE),
-	HTML_ATTR(BQ,TITLE),
-	HTML_ATTRIBUTES(BQ)
-};
-
-static HTAttr br_attr[HTML_BR_ATTRIBUTES+1] = {
-	HTML_ATTR(BR,CLASS),
-	HTML_ATTR(BR,CLEAR),
-	HTML_ATTR(BR,ID),
-	HTML_ATTR(BR,STYLE),
-	HTML_ATTR(BR,TITLE),
-	HTML_ATTRIBUTES(BR)
-};
-
-static HTAttr button_attr[HTML_BUTTON_ATTRIBUTES+1] = {
-	HTML_ATTR(BUTTON,ACCESSKEY),
-	HTML_ATTR(BUTTON,CLASS),
-	HTML_ATTR(BUTTON,DIR),
-	HTML_ATTR(BUTTON,DISABLED),
-	HTML_ATTR(BUTTON,ID),
-	HTML_ATTR(BUTTON,LANG),
-	HTML_ATTR(BUTTON,NAME),
-	HTML_ATTR(BUTTON,STYLE),
-	HTML_ATTR(BUTTON,TABINDEX),
-	HTML_ATTR(BUTTON,TITLE),
-	HTML_ATTR(BUTTON,TYPE),
-	HTML_ATTR(BUTTON,VALUE),
-	HTML_ATTRIBUTES(BUTTON),
-};
-
-static HTAttr col_attr[HTML_COL_ATTRIBUTES+1] = {
-	HTML_ATTR(COL,CLASS),
-	HTML_ATTR(COL,DIR),
-	HTML_ATTR(COL,ID),
-	HTML_ATTR(COL,LANG),
-	HTML_ATTR(COL,SPAN),
-	HTML_ATTR(COL,STYLE),
-	HTML_ATTR(COL,TITLE),
-	HTML_ATTR(COL,WIDTH),
-	HTML_ATTRIBUTES(COL)
-};
-
-static HTAttr changes_attr[HTML_CHANGES_ATTRIBUTES+1] = {
-	HTML_ATTR(CHANGES,CITE),
-	HTML_ATTR(CHANGES,CLASS),
-	HTML_ATTR(CHANGES,DATETIME),
-	HTML_ATTR(CHANGES,DIR),
-	HTML_ATTR(CHANGES,ID),
-	HTML_ATTR(CHANGES,LANG),
-	HTML_ATTR(CHANGES,STYLE),
-	HTML_ATTR(CHANGES,TITLE),
-	HTML_ATTRIBUTES(CHANGES)
-};
-
-static HTAttr font_attr[HTML_FONT_ATTRIBUTES+1] = {
-	HTML_ATTR(FONT,CLASS),
-	HTML_ATTR(FONT,COLOR),
-	HTML_ATTR(FONT,DIR),
-	HTML_ATTR(FONT,FACE),
-	HTML_ATTR(FONT,ID),
-	HTML_ATTR(FONT,LANG),
-	HTML_ATTR(FONT,SIZE),
-	HTML_ATTR(FONT,STYLE),
-	HTML_ATTR(FONT,TITLE),
-	HTML_ATTRIBUTES(FONT)
-};
-
-static HTAttr form_attr[HTML_FORM_ATTRIBUTES+1] = {
-	HTML_ATTR(FORM,ACCEPT),
-	{ (char *) "ACCEPT-CHARSET" }, /* HTML_ATTR(FORM,ACCEPT_CHARSET) */
-	HTML_ATTR(FORM,ACTION),
-	HTML_ATTR(FORM,CLASS),
-	HTML_ATTR(FORM,DIR),
-	HTML_ATTR(FORM,ENCTYPE),
-	HTML_ATTR(FORM,ID),
-	HTML_ATTR(FORM,LANG),
-	HTML_ATTR(FORM,METHOD),
-	HTML_ATTR(FORM,STYLE),
-	HTML_ATTR(FORM,TARGET),
-	HTML_ATTR(FORM,TITLE),
-	HTML_ATTRIBUTES(FORM)
-};
-
-static HTAttr gen_attr[HTML_GEN_ATTRIBUTES+1] = { /* General, for many things */
-	HTML_ATTR(GEN,CLASS),
-	HTML_ATTR(GEN,DIR),
-	HTML_ATTR(GEN,ID),
-	HTML_ATTR(GEN,LANG),
-	HTML_ATTR(GEN,STYLE),
-	HTML_ATTR(GEN,TITLE),
-	HTML_ATTRIBUTES(GEN)
-};
-
-static HTAttr block_attr[HTML_BLOCK_ATTRIBUTES+1] = { /* DIV, SPAN, H1-H6 */
-	HTML_ATTR(BLOCK,ALIGN),
-	HTML_ATTR(BLOCK,CLASS),
-	HTML_ATTR(BLOCK,DIR),
-	HTML_ATTR(BLOCK,ID),
-	HTML_ATTR(BLOCK,LANG),
-	HTML_ATTR(BLOCK,STYLE),
-	HTML_ATTR(BLOCK,TITLE),
-	HTML_ATTRIBUTES(BLOCK)
-};
-
-static HTAttr head_attr[HTML_HEAD_ATTRIBUTES+1] = {
-	HTML_ATTR(HEAD,DIR),
-	HTML_ATTR(HEAD,LANG),
-	HTML_ATTR(HEAD,PROFILE),
-	HTML_ATTRIBUTES(HEAD)
-};
-
-static HTAttr hr_attr[HTML_HR_ATTRIBUTES+1] = {
-	HTML_ATTR(HR,ALIGN),
-	HTML_ATTR(HR,CLASS),
-	HTML_ATTR(HR,DIR),
-	HTML_ATTR(HR,ID),
-	HTML_ATTR(HR,LANG),
-	HTML_ATTR(HR,NOSHADE),
-	HTML_ATTR(HR,SIZE),
-	HTML_ATTR(HR,STYLE),
-	HTML_ATTR(HR,TITLE),
-	HTML_ATTR(HR,WIDTH),
-	HTML_ATTRIBUTES(HR)
-};
-
-static HTAttr html_attr[HTML_HTML_ATTRIBUTES+1] = {
-	HTML_ATTR(HTML,DIR),
-	HTML_ATTR(HTML,LANG),
-	HTML_ATTR(HTML,VERSION),
-	HTML_ATTRIBUTES(HTML)
-};
-
-static HTAttr iframe_attr[HTML_IFRAME_ATTRIBUTES+1] = {
-	HTML_ATTR(IFRAME,ALIGN),
-	HTML_ATTR(IFRAME,CLASS),
-	HTML_ATTR(IFRAME,FRAMEBORDER),
-	HTML_ATTR(IFRAME,HEIGHT),
-	HTML_ATTR(IFRAME,ID),
-	HTML_ATTR(IFRAME,LONGDESC),
-	HTML_ATTR(IFRAME,MARGINHEIGHT),
-	HTML_ATTR(IFRAME,MARGINWIDTH),
-	HTML_ATTR(IFRAME,NAME),
-	HTML_ATTR(IFRAME,SCROLLING),
-	HTML_ATTR(IFRAME,SRC),
-	HTML_ATTR(IFRAME,STYLE),
-	HTML_ATTR(IFRAME,TARGET),
-	HTML_ATTR(IFRAME,TITLE),
-	HTML_ATTR(IFRAME,WIDTH),
-	HTML_ATTRIBUTES(IFRAME)
-};
-
-static HTAttr img_attr[HTML_IMG_ATTRIBUTES+1] = {	/* IMG attributes */
-	HTML_ATTR(IMG,ALIGN),
-	HTML_ATTR(IMG,ALT),
-	HTML_ATTR(IMG,BORDER),
-	HTML_ATTR(IMG,CLASS),
-	HTML_ATTR(IMG,DIR),
-	HTML_ATTR(IMG,HEIGHT),
-	HTML_ATTR(IMG,HSPACE),
-	HTML_ATTR(IMG,ID),
-	HTML_ATTR(IMG,ISMAP),
-	HTML_ATTR(IMG,LANG),
-	HTML_ATTR(IMG,LONGDESC),
-	HTML_ATTR(IMG,SRC),
-	HTML_ATTR(IMG,STYLE),
-	HTML_ATTR(IMG,TITLE),
-	HTML_ATTR(IMG,USEMAP),
-	HTML_ATTR(IMG,VSPACE),
-	HTML_ATTR(IMG,WIDTH),
-	HTML_ATTRIBUTES(IMG)
-};
-
-static HTAttr input_attr[HTML_INPUT_ATTRIBUTES+1] = {
-	HTML_ATTR(INPUT,ACCEPT),
-	HTML_ATTR(INPUT,ACCESSKEY),
-	HTML_ATTR(INPUT,ALIGN),
-	HTML_ATTR(INPUT,ALT),
-	HTML_ATTR(INPUT,CHECKED),
-	HTML_ATTR(INPUT,CLASS),
-	HTML_ATTR(INPUT,DIR),
-	HTML_ATTR(INPUT,DISABLED),
-	HTML_ATTR(INPUT,ID),
-	HTML_ATTR(INPUT,LANG),
-	HTML_ATTR(INPUT,MAXLENGTH),
-	HTML_ATTR(INPUT,NAME),
-	HTML_ATTR(INPUT,READONLY),
-	HTML_ATTR(INPUT,SIZE),
-	HTML_ATTR(INPUT,SRC),
-	HTML_ATTR(INPUT,STYLE),
-	HTML_ATTR(INPUT,TABINDEX),
-	HTML_ATTR(INPUT,TITLE),
-	HTML_ATTR(INPUT,TYPE),
-	HTML_ATTR(INPUT,USEMAP),
-	HTML_ATTR(INPUT,VALUE),
-	HTML_ATTRIBUTES(INPUT)
-};
-
-static HTAttr isindex_attr[HTML_ISINDEX_ATTRIBUTES+1] = {
-	HTML_ATTR(ISINDEX,CLASS),
-	HTML_ATTR(ISINDEX,DIR),
-	HTML_ATTR(ISINDEX,ID),
-	HTML_ATTR(ISINDEX,LANG),
-	HTML_ATTR(ISINDEX,PROMPT),
-	HTML_ATTR(ISINDEX,STYLE),
-	HTML_ATTR(ISINDEX,TITLE),
-	HTML_ATTRIBUTES(ISINDEX)
-};
-
-static HTAttr label_attr[HTML_LABEL_ATTRIBUTES+1] = {
-	HTML_ATTR(LABEL,ACCESSKEY),
-	HTML_ATTR(LABEL,CLASS),
-	HTML_ATTR(LABEL,DIR),
-	HTML_ATTR(LABEL,FOR),
-	HTML_ATTR(LABEL,ID),
-	HTML_ATTR(LABEL,LANG),
-	HTML_ATTR(LABEL,STYLE),
-	HTML_ATTR(LABEL,TITLE),
-	HTML_ATTRIBUTES(LABEL)
-};
-
-static HTAttr legend_attr[HTML_LEGEND_ATTRIBUTES+1] = {
-	HTML_ATTR(LEGEND,ACCESSKEY),
-	HTML_ATTR(LEGEND,ALIGN),
-	HTML_ATTR(LEGEND,CLASS),
-	HTML_ATTR(LEGEND,DIR),
-	HTML_ATTR(LEGEND,ID),
-	HTML_ATTR(LEGEND,LANG),
-	HTML_ATTR(LEGEND,STYLE),
-	HTML_ATTR(LEGEND,TITLE),
-	HTML_ATTRIBUTES(LEGEND)
-};
-
-static HTAttr li_attr[HTML_LI_ATTRIBUTES+1] = {
-	HTML_ATTR(LI,CLASS),
-	HTML_ATTR(LI,COMPACT),
-	HTML_ATTR(LI,DIR),
-	HTML_ATTR(LI,ID),
-	HTML_ATTR(LI,LANG),
-	HTML_ATTR(LI,STYLE),
-	HTML_ATTR(LI,TITLE),
-	HTML_ATTR(LI,TYPE),
-	HTML_ATTR(LI,VALUE),
-	HTML_ATTRIBUTES(LI)
-};
-
-static HTAttr link_attr[HTML_LINK_ATTRIBUTES+1] = {	/* link attributes */
-	HTML_ATTR(LINK,CHARSET),
-	HTML_ATTR(LINK,CLASS),
-	HTML_ATTR(LINK,DIR),
-	HTML_ATTR(LINK,HREF),
-	HTML_ATTR(LINK,HREFLANG),
-	HTML_ATTR(LINK,ID),
-	HTML_ATTR(LINK,LANG),
-	HTML_ATTR(LINK,MEDIA),
-	HTML_ATTR(LINK,REL),
-	HTML_ATTR(LINK,REV),
-	HTML_ATTR(LINK,STYLE),
-	HTML_ATTR(LINK,TARGET),
-	HTML_ATTR(LINK,TITLE),
-	HTML_ATTR(LINK,TYPE),
-	HTML_ATTRIBUTES(LINK)
-};
-
-static HTAttr map_attr[HTML_MAP_ATTRIBUTES+1] = {
-	HTML_ATTR(MAP,CLASS),
-	HTML_ATTR(MAP,DIR),
-	HTML_ATTR(MAP,ID),
-	HTML_ATTR(MAP,LANG),
-	HTML_ATTR(MAP,NAME),
-	HTML_ATTR(MAP,STYLE),
-	HTML_ATTR(MAP,TITLE),
-	HTML_ATTRIBUTES(MAP)
-};
-
-static HTAttr meta_attr[HTML_META_ATTRIBUTES+1] = {
-	HTML_ATTR(META,CONTENT),
-	HTML_ATTR(META,DIR),
-	{ (char *)"HTTP-EQUIV" },   /* HTML_ATTR(META,HTTP_EQUIV) */
-	HTML_ATTR(META,LANG),
-	HTML_ATTR(META,NAME),
-	HTML_ATTR(META,SCHEME),
-	HTML_ATTRIBUTES(META)
-};
-
-static HTAttr nextid_attr[HTML_NEXTID_ATTRIBUTES+1] = {
-	{ (char *)"N" },
-	{ 0 }	/* Terminate list */
-};
-
-static HTAttr object_attr[HTML_OBJECT_ATTRIBUTES+1] = {	/* object attributes */
-	HTML_ATTR(OBJECT,ALIGN),
-	HTML_ATTR(OBJECT,ARCHIVE),
-	HTML_ATTR(OBJECT,BORDER),
-	HTML_ATTR(OBJECT,CLASS),
-	HTML_ATTR(OBJECT,CLASSID),
-	HTML_ATTR(OBJECT,CODEBASE),
-	HTML_ATTR(OBJECT,CODETYPE),
-	HTML_ATTR(OBJECT,DATA),
-	HTML_ATTR(OBJECT,DECLARE),
-	HTML_ATTR(OBJECT,DIR),
-	HTML_ATTR(OBJECT,HEIGHT),
-	HTML_ATTR(OBJECT,HSPACE),
-	HTML_ATTR(OBJECT,ID),
-	HTML_ATTR(OBJECT,LANG),
-	HTML_ATTR(OBJECT,NAME),
-	HTML_ATTR(OBJECT,STANDBY),
-	HTML_ATTR(OBJECT,STYLE),
-	HTML_ATTR(OBJECT,TABINDEX),
-	HTML_ATTR(OBJECT,TITLE),
-	HTML_ATTR(OBJECT,TYPE),
-	HTML_ATTR(OBJECT,USEMAP),
-	HTML_ATTR(OBJECT,VSPACE),
-	HTML_ATTR(OBJECT,WIDTH),
-	HTML_ATTRIBUTES(OBJECT)
-};
-
-static HTAttr ol_attr[HTML_OL_ATTRIBUTES+1] = {
-	HTML_ATTR(OL,CLASS),
-	HTML_ATTR(OL,COMPACT),
-	HTML_ATTR(OL,DIR),
-	HTML_ATTR(OL,ID),
-	HTML_ATTR(OL,LANG),
-	HTML_ATTR(OL,START),
-	HTML_ATTR(OL,STYLE),
-	HTML_ATTR(OL,TITLE),
-	HTML_ATTR(OL,TYPE),
-	HTML_ATTRIBUTES(OL)
-};
-
-static HTAttr optgroup_attr[HTML_OPTGROUP_ATTRIBUTES+1] = {
-	HTML_ATTR(OPTGROUP,CLASS),
-	HTML_ATTR(OPTGROUP,DISABLED),
-	HTML_ATTR(OPTGROUP,DIR),
-	HTML_ATTR(OPTGROUP,ID),
-	HTML_ATTR(OPTGROUP,LABEL),
-	HTML_ATTR(OPTGROUP,LANG),
-	HTML_ATTR(OPTGROUP,STYLE),
-	HTML_ATTR(OPTGROUP,TITLE),
-	HTML_ATTRIBUTES(OPTGROUP)
-};
-
-static HTAttr option_attr[HTML_OPTION_ATTRIBUTES+1] = {
-	HTML_ATTR(OPTION,CLASS),
-	HTML_ATTR(OPTION,DISABLED),
-	HTML_ATTR(OPTION,DIR),
-	HTML_ATTR(OPTION,ID),
-	HTML_ATTR(OPTION,LABEL),
-	HTML_ATTR(OPTION,LANG),
-	HTML_ATTR(OPTION,SELECTED),
-	HTML_ATTR(OPTION,STYLE),
-	HTML_ATTR(OPTION,TITLE),
-	HTML_ATTR(OPTION,VALUE),
-	HTML_ATTRIBUTES(OPTION)
-};
-
-static HTAttr param_attr[HTML_PARAM_ATTRIBUTES+1] = {
-	HTML_ATTR(PARAM,ID),
-	HTML_ATTR(PARAM,NAME),
-	HTML_ATTR(PARAM,TYPE),
-	HTML_ATTR(PARAM,VALUE),
-	HTML_ATTR(PARAM,VALUETYPE),
-	HTML_ATTRIBUTES(PARAM)
-};
-
-static HTAttr pre_attr[HTML_PRE_ATTRIBUTES+1] = {
-	HTML_ATTR(PRE,CLASS),
-	HTML_ATTR(PRE,DIR),
-	HTML_ATTR(PRE,ID),
-	HTML_ATTR(PRE,LANG),
-	HTML_ATTR(PRE,STYLE),
-	HTML_ATTR(PRE,TITLE),
-	HTML_ATTR(PRE,WIDTH),
-	HTML_ATTRIBUTES(PRE)
-};
-
-static HTAttr script_attr[HTML_SCRIPT_ATTRIBUTES+1] = {
-	HTML_ATTR(SCRIPT,CHARSET),
-	HTML_ATTR(SCRIPT,DEFER),
-	HTML_ATTR(SCRIPT,LANGUAGE),
-	HTML_ATTR(SCRIPT,SRC),
-	HTML_ATTR(SCRIPT,TYPE),
-	HTML_ATTRIBUTES(SCRIPT)
-};
-
-static HTAttr select_attr[HTML_SELECT_ATTRIBUTES+1] = {
-	HTML_ATTR(SELECT,CLASS),
-	HTML_ATTR(SELECT,DIR),
-	HTML_ATTR(SELECT,DISABLED),
-	HTML_ATTR(SELECT,ID),
-	HTML_ATTR(SELECT,LANG),
-	HTML_ATTR(SELECT,MULTIPLE),
-	HTML_ATTR(SELECT,NAME),
-	HTML_ATTR(SELECT,SIZE),
-	HTML_ATTR(SELECT,STYLE),
-	HTML_ATTR(SELECT,TABINDEX),
-	HTML_ATTR(SELECT,TITLE),
-	HTML_ATTRIBUTES(SELECT)
-};
-
-static HTAttr style_attr[HTML_STYLE_ATTRIBUTES+1] = {
-	HTML_ATTR(STYLE,DIR),
-	HTML_ATTR(STYLE,LANG),
-	HTML_ATTR(STYLE,MEDIA),
-	HTML_ATTR(STYLE,TITLE),
-	HTML_ATTR(STYLE,TYPE),
-	HTML_ATTRIBUTES(STYLE)
-};
-
-static HTAttr table_attr[HTML_TABLE_ATTRIBUTES+1] = {
-	HTML_ATTR(TABLE,ALIGN),
-	HTML_ATTR(TABLE,BGCOLOR),
-	HTML_ATTR(TABLE,BORDER),
-	HTML_ATTR(TABLE,CELLPADDING),
-	HTML_ATTR(TABLE,CELLSPACING),
-	HTML_ATTR(TABLE,CLASS),
-	HTML_ATTR(TABLE,DIR),
-	HTML_ATTR(TABLE,FRAME),
-	HTML_ATTR(TABLE,ID),
-	HTML_ATTR(TABLE,LANG),
-	HTML_ATTR(TABLE,RULES),
-	HTML_ATTR(TABLE,SUMMARY),
-	HTML_ATTR(TABLE,STYLE),
-	HTML_ATTR(TABLE,TITLE),
-	HTML_ATTR(TABLE,WIDTH),
-	HTML_ATTRIBUTES(TABLE)
-};
-
-static HTAttr tele_attr[HTML_TELE_ATTRIBUTES+1] = {
-	HTML_ATTR(TELE,ALIGN),
-	HTML_ATTR(TELE,CHAR),
-	HTML_ATTR(TELE,CHAROFF),
-	HTML_ATTR(TELE,CLASS),
-	HTML_ATTR(TELE,DIR),
-	HTML_ATTR(TELE,ID),
-	HTML_ATTR(TELE,LANG),
-	HTML_ATTR(TELE,STYLE),
-	HTML_ATTR(TELE,TITLE),
-	HTML_ATTR(TELE,VALIGN),
-	HTML_ATTRIBUTES(TELE)
-};
-
-static HTAttr td_attr[HTML_TD_ATTRIBUTES+1] = {
-	HTML_ATTR(TD,ABBR),
-	HTML_ATTR(TD,ALIGN),
-	HTML_ATTR(TD,AXIS),
-	HTML_ATTR(TD,BGCOLOR),
-	HTML_ATTR(TD,CHAR),
-	HTML_ATTR(TD,CHAROFF),
-	HTML_ATTR(TD,CLASS),
-	HTML_ATTR(TD,COLSPAN),
-	HTML_ATTR(TD,DIR),
-	HTML_ATTR(TD,ID),
-	HTML_ATTR(TD,HEADERS),
-	HTML_ATTR(TD,HEIGHT),
-	HTML_ATTR(TD,LANG),
-	HTML_ATTR(TD,NOWRAP),
-	HTML_ATTR(TD,ROWSPAN),
-	HTML_ATTR(TD,SCOPE),
-	HTML_ATTR(TD,STYLE),
-	HTML_ATTR(TD,TITLE),
-	HTML_ATTR(TD,VALIGN),
-	HTML_ATTR(TD,WIDTH),
-	HTML_ATTRIBUTES(TD)
-};
-
-static HTAttr textarea_attr[HTML_TEXTAREA_ATTRIBUTES+1] = {
-	HTML_ATTR(TEXTAREA,CLASS),
-	HTML_ATTR(TEXTAREA,COLS),
-	HTML_ATTR(TEXTAREA,DIR),
-	HTML_ATTR(TEXTAREA,DISABLED),
-	HTML_ATTR(TEXTAREA,ID),
-	HTML_ATTR(TEXTAREA,LANG),
-	HTML_ATTR(TEXTAREA,NAME),
-	HTML_ATTR(TEXTAREA,READONLY),
-	HTML_ATTR(TEXTAREA,ROWS),
-	HTML_ATTR(TEXTAREA,STYLE),
-	HTML_ATTR(TEXTAREA,TABINDEX),
-	HTML_ATTR(TEXTAREA,TITLE),
-	HTML_ATTRIBUTES(TEXTAREA)
-};
-
-static HTAttr title_attr[HTML_TITLE_ATTRIBUTES+1] = {
-	HTML_ATTR(TITLE,DIR),
-	HTML_ATTR(TITLE,LANG),
-	HTML_ATTRIBUTES(TITLE)
-};
-
-static HTAttr ul_attr[HTML_UL_ATTRIBUTES+1] = {
-	HTML_ATTR(UL,CLASS),
-	HTML_ATTR(UL,COMPACT),
-	HTML_ATTR(UL,DIR),
-	HTML_ATTR(UL,ID),
-	HTML_ATTR(UL,LANG),
-	HTML_ATTR(UL,STYLE),
-	HTML_ATTR(UL,TITLE),
-	HTML_ATTR(UL,TYPE),
-	HTML_ATTRIBUTES(UL)
-};
-
-/*
- **	ELEMENTS
- **	Must match definitions in HTMLPDTD.html!
- **	Must be in alphabetical order.
- **
- **    Name,	Attributes,		content
- */
-static HTTag tags[HTML_ELEMENTS] = {
-	{ "A"	, a_attr,	HTML_A_ATTRIBUTES },
-	{ "ABBR"    , gen_attr,     HTML_GEN_ATTRIBUTES },
-	{ "ACRONYM"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "ADDRESS"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "APPLET"  , applet_attr,  HTML_APPLET_ATTRIBUTES },
-	{ "AREA"	, area_attr,	HTML_AREA_ATTRIBUTES },
-	{ "B"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "BASE"	, base_attr,	HTML_BASE_ATTRIBUTES },
-	{ "BASEFONT", font_attr,	HTML_FONT_ATTRIBUTES },
-	{ "BDO"     , bdo_attr,     HTML_BDO_ATTRIBUTES },
-	{ "BIG"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "BLOCKQUOTE", bq_attr,	HTML_BQ_ATTRIBUTES },
-	{ "BODY"	, body_attr,	HTML_BODY_ATTRIBUTES },
-	{ "BR"	, br_attr,	HTML_BR_ATTRIBUTES },
-	{ "BUTTON"	, button_attr,	HTML_BUTTON_ATTRIBUTES },
-	{ "CAPTION"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "CENTER"	, no_attr,	0 },
-	{ "CITE"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "CODE"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "COL"	, col_attr,	HTML_COL_ATTRIBUTES },
-	{ "COLGROUP", col_attr,	HTML_COL_ATTRIBUTES },
-	{ "DD"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "DEL"	, changes_attr,	HTML_CHANGES_ATTRIBUTES },
-	{ "DFN"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "DIR"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "DIV"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "DL"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "DT"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "EM"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "FIELDSET", gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "FONT"	, font_attr,	HTML_FONT_ATTRIBUTES },
-	{ "FORM" 	, form_attr,	HTML_FORM_ATTRIBUTES },
-	{ "FRAME"	, frame_attr,	HTML_FRAME_ATTRIBUTES },
-	{ "FRAMESET", frameset_attr,HTML_FRAMESET_ATTRIBUTES },
-	{ "H1"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "H2"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "H3"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "H4"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "H5"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "H6"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "HEAD"	, head_attr,	HTML_HEAD_ATTRIBUTES },
-	{ "HR"	, hr_attr,	HTML_HR_ATTRIBUTES },
-	{ "HTML"	, html_attr,	HTML_HTML_ATTRIBUTES },
-	{ "I"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "IFRAME"	, iframe_attr,	HTML_IFRAME_ATTRIBUTES },
-	{ "IMG"     , img_attr,	HTML_IMG_ATTRIBUTES },
-	{ "INPUT"	, input_attr,	HTML_INPUT_ATTRIBUTES },
-	{ "INS"	, changes_attr,	HTML_CHANGES_ATTRIBUTES },
-	{ "ISINDEX" , isindex_attr,	HTML_ISINDEX_ATTRIBUTES },
-	{ "KBD"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "LABEL"	, label_attr,	HTML_LABEL_ATTRIBUTES },
-	{ "LEGEND"	, legend_attr,	HTML_LEGEND_ATTRIBUTES },
-	{ "LI"	, li_attr,	HTML_LI_ATTRIBUTES },
-	{ "LINK"	, link_attr,	HTML_LINK_ATTRIBUTES },
-	{ "MAP"	, map_attr,	HTML_MAP_ATTRIBUTES },
-	{ "MENU"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "META"	, meta_attr,	HTML_META_ATTRIBUTES },
-	{ "NEXTID"  , nextid_attr,	1 },
-	{ "NOFRAMES", gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "NOSCRIPT", gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "OBJECT"	, object_attr,	HTML_OBJECT_ATTRIBUTES },
-	{ "OL"	, ol_attr,	HTML_OL_ATTRIBUTES },
-	{ "OPTGROUP", optgroup_attr,HTML_OPTGROUP_ATTRIBUTES },
-	{ "OPTION"	, option_attr,	HTML_OPTION_ATTRIBUTES },
-	{ "P"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "PARAM"	, param_attr,	HTML_PARAM_ATTRIBUTES },
-	{ "PRE"	, pre_attr,	HTML_PRE_ATTRIBUTES },
-	{ "Q"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "S"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "SAMP"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "SCRIPT"	, script_attr,	HTML_SCRIPT_ATTRIBUTES },
-	{ "SELECT"	, select_attr,	HTML_SELECT_ATTRIBUTES },
-	{ "SMALL"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "SPAN"	, block_attr,	HTML_BLOCK_ATTRIBUTES },
-	{ "STRIKE"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "STRONG"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "STYLE"	, style_attr,	HTML_STYLE_ATTRIBUTES },
-	{ "SUB"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "SUP"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "TABLE"	, table_attr,	HTML_TABLE_ATTRIBUTES },
-	{ "TBODY"	, tele_attr,	HTML_TELE_ATTRIBUTES },
-	{ "TD"	, td_attr,	HTML_TD_ATTRIBUTES },
-	{ "TEXTAREA", textarea_attr,HTML_TEXTAREA_ATTRIBUTES },
-	{ "TFOOT"	, tele_attr,	HTML_TELE_ATTRIBUTES },
-	{ "TH"	, td_attr,	HTML_TD_ATTRIBUTES },
-	{ "THEAD"	, tele_attr,	HTML_TELE_ATTRIBUTES },
-	{ "TITLE"	, title_attr,	HTML_TITLE_ATTRIBUTES },
-	{ "TR"	, tele_attr,	HTML_TELE_ATTRIBUTES },
-	{ "TT"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "U"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	{ "UL"	, ul_attr,	HTML_UL_ATTRIBUTES },
-	{ "VAR"	, gen_attr,	HTML_GEN_ATTRIBUTES },
-	//
-	{ "LUA" , gen_attr, HTML_GEN_ATTRIBUTES },
-};
-
-static SGML_dtd HTMLP_dtd = {
-	tags,
-	HTML_ELEMENTS
-};
-
-static SGML_dtd * DTD = &HTMLP_dtd;
-
-SGML_dtd * HTML_dtd (void)
-{
-	return DTD;
-}
-
-}// namespace
-

From c21e133c6db197a0f433409d9d952e615cd31c34 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 3 May 2019 00:26:16 +0300
Subject: [PATCH 70/75] Changed: background, img, button images can be from
 local/bnp or remote url

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp | 84 +++++++--------------------------
 1 file changed, 16 insertions(+), 68 deletions(-)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 6605fa591..be12bd862 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -699,7 +699,20 @@ namespace NLGUI
 	// Add a image download request in the multi_curl
 	void CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style, TImageType type)
 	{
-		string finalUrl = upgradeInsecureUrl(getAbsoluteUrl(url));
+		std::string finalUrl;
+		img->setModulateGlobalColor(style.GlobalColor);
+
+		// load the image from local files/bnp
+		std::string image = CFile::getPath(url) + CFile::getFilenameWithoutExtension(url) + ".tga";
+		if (lookupLocalFile(finalUrl, image.c_str(), false))
+		{
+			setImage(img, image, type);
+			setImageSize(img, style);
+			return;
+		}
+
+		// TODO: if no image in cache, nothing is visible
+		finalUrl = upgradeInsecureUrl(getAbsoluteUrl(url));
 
 		// use requested url for local name (cache)
 		string dest = localImageName(url);
@@ -2801,8 +2814,6 @@ namespace NLGUI
 			paragraphChange ();
 		}
 
-		string finalUrl;
-
 		// No more text in this text view
 		_CurrentViewLink = NULL;
 
@@ -2810,51 +2821,8 @@ namespace NLGUI
 		CViewBitmap *newImage = new CViewBitmap (TCtorParam());
 		newImage->setId(id);
 
-		//
-		// 1/ try to load the image with the old system (local files in bnp)
-		//
-		string image = CFile::getPath(img) + CFile::getFilenameWithoutExtension(img) + ".tga";
-		if (lookupLocalFile (finalUrl, image.c_str(), false))
-		{
-			newImage->setRenderLayer(getRenderLayer()+1);
-			image = finalUrl;
-		}
-		else
-		{
-			//
-			// 2/ if it doesn't work, try to load the image in cache
-			//
-			image = localImageName(img);
-
-			if (reloadImg && CFile::fileExists(image))
-				CFile::deleteFile(image);
-
-			if (lookupLocalFile (finalUrl, image.c_str(), false))
-			{
-				// don't display image that are not power of 2
-				try
-				{
-					uint32 w, h;
-					CBitmap::loadSize (image, w, h);
-					if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures()))
-						image = "web_del.tga";
-				}
-				catch(const NLMISC::Exception &e)
-				{
-					nlwarning(e.what());
-					image = "web_del.tga";
-				}
-			}
-			else
-			{
-				// no image in cache
-				image = "web_del.tga";
-			}
-
-			addImageDownload(img, newImage, style);
-		}
-		newImage->setTexture (image);
-		newImage->setModulateGlobalColor(style.GlobalColor);
+		addImageDownload(img, newImage, style, TImageType::NormalImage);
+		newImage->setRenderLayer(getRenderLayer()+1);
 
 		getParagraph()->addChild(newImage);
 		paragraphChange ();
@@ -3058,26 +3026,6 @@ namespace NLGUI
 			if(id == -1)
 			{
 				normal = localImageName(normalBitmap);
-				if(!CFile::fileExists(normal))
-				{
-					normal = "web_del.tga";
-				}
-				else
-				{
-					try
-					{
-						uint32 w, h;
-						CBitmap::loadSize(normal, w, h);
-						if (w == 0 || h == 0)
-							normal = "web_del.tga";
-					}
-					catch(const NLMISC::Exception &e)
-					{
-						nlwarning(e.what());
-						normal = "web_del.tga";
-					}
-				}
-
 				addImageDownload(normalBitmap, ctrlButton, style);
 			}
 		}

From 23220c6b96dd2665784704bc97c800e6aca2365b Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 3 May 2019 08:59:07 +0300
Subject: [PATCH 71/75] Changed: Add extra url parameters only for trusted
 domain requests

--HG--
branch : develop
---
 code/ryzom/client/src/interface_v3/group_html_webig.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp
index 8d6ea05af..c7ee1a6c3 100644
--- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp
+++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp
@@ -357,6 +357,9 @@ void CGroupHTMLAuth::addHTTPGetParams (string &url, bool trustedDomain)
 
 void CGroupHTMLAuth::addHTTPPostParams (SFormFields &formfields, bool trustedDomain)
 {
+	// no extras parameters added to url if not in trusted domains list
+	if (!trustedDomain) return;
+
 	if(!UserEntity || !NetMngr.getLoginCookie().isValid()) return;
 
 	uint32 cid = NetMngr.getLoginCookie().getUserId() * 16 + PlayerSelectedSlot;

From 9f9c5d4106dc7c8d04632260458c2f648622752c Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 3 May 2019 08:59:12 +0300
Subject: [PATCH 72/75] Fixed: Background image persisted page reload

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index be12bd862..e6f02b7b1 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -4193,6 +4193,7 @@ namespace NLGUI
 
 		// Reset default background color
 		setBackgroundColor (BgColor);
+		setBackground ("blank.tga", true, false);
 
 		paragraphChange ();
 	}

From 4f4ba7120d12d34c377cb4350715eeef1a7d54a4 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Fri, 3 May 2019 08:59:19 +0300
Subject: [PATCH 73/75] Changed: Set background image from html or body

--HG--
branch : develop
---
 code/nel/include/nel/gui/group_html.h |  3 +
 code/nel/src/gui/group_html.cpp       | 91 ++++++++++++++++-----------
 2 files changed, 59 insertions(+), 35 deletions(-)

diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index 2c6737446..fc29c840d 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -816,6 +816,9 @@ namespace NLGUI
 		// :before, :after rendering
 		void renderPseudoElement(const std::string &pseudo, const CHtmlElement &elm);
 
+		// apply background from current style (for html, body)
+		void applyBackground(const CHtmlElement &elm);
+
 		// HTML elements
 		void htmlA(const CHtmlElement &elm);
 		void htmlAend(const CHtmlElement &elm);
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index e6f02b7b1..e11369014 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -3379,6 +3379,13 @@ namespace NLGUI
 				bitmap->setRenderLayer(-2);
 				bitmap->setScale(scale);
 				bitmap->setTile(tile);
+
+				// clear size ref for non-scaled image or it does not show up
+				if (scale || tile)
+					bitmap->setSizeRef("wh");
+				else
+					bitmap->setSizeRef("");
+
 				addImageDownload(bgtex, view);
 			}
 		}
@@ -5015,6 +5022,52 @@ namespace NLGUI
 		_CellParams.push_back (cellParams);
 	}
 
+	// ***************************************************************************
+	void CGroupHTML::applyBackground(const CHtmlElement &elm)
+	{
+		bool root = elm.Value == "html" || elm.Value == "body";
+
+		// non-empty image
+		if (_Style.hasStyle("background-image"))
+		{
+			// value '1' and 'background-scale' are ryzom only
+			bool repeat = _Style.checkStyle("background-repeat", "1") || _Style.checkStyle("background-repeat", "repeat");
+			bool scale = _Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "100% 100%");
+			std::string image = trim(_Style.getStyle("background-image"));
+			string::size_type texExt = toLower(image).find("url(");
+			if (texExt != string::npos)
+			{
+				image = image.substr(texExt+4, image.size()-texExt-5);
+			}
+			if (!image.empty())
+			{
+				if (root)
+				{
+					setBackground (image, scale, repeat);
+				}
+				// TODO: else
+
+				// default background color is transparent, so image does not show
+				if (!_Style.hasStyle("background-color"))
+				{
+					_Style.applyStyle("background-color: #fff;");
+				}
+			}
+		}
+
+		if (_Style.hasStyle("background-color"))
+		{
+			CRGBA bgColor = _Style.Current.BackgroundColor;
+			scanHTMLColor(elm.getAttribute("bgcolor").c_str(), bgColor);
+			if (root)
+			{
+				setBackgroundColor(bgColor);
+			}
+			// TODO: else 
+		}
+
+	}
+
 	// ***************************************************************************
 	void CGroupHTML::htmlA(const CHtmlElement &elm)
 	{
@@ -5084,39 +5137,7 @@ namespace NLGUI
 			_Style.applyStyle("background-color: " + elm.getAttribute("bgcolor"));
 		}
 
-		if (_Style.hasStyle("background-color"))
-		{
-			CRGBA bgColor = _Style.Current.BackgroundColor;
-			scanHTMLColor(elm.getAttribute("bgcolor").c_str(), bgColor);
-			setBackgroundColor(bgColor);
-		}
-
-		if (elm.hasNonEmptyAttribute("style"))
-		{
-			string style = elm.getAttribute("style");
-
-			TStyle styles = parseStyle(style);
-			TStyle::iterator	it;
-
-			it = styles.find("background-repeat");
-			bool repeat = (it != styles.end() && it->second == "1");
-
-			// Webig only
-			it = styles.find("background-scale");
-			bool scale = (it != styles.end() && it->second == "1");
-
-			it = styles.find("background-image");
-			if (it != styles.end())
-			{
-				string image = it->second;
-				string::size_type texExt = toLower(image).find("url(");
-				// Url image
-				if (texExt != string::npos)
-					// Remove url()
-					image = image.substr(4, image.size()-5);
-				setBackground (image, scale, repeat);
-			}
-		}
+		applyBackground(elm);
 
 		renderPseudoElement(":before", elm);
 	}
@@ -5468,7 +5489,7 @@ namespace NLGUI
 			_Style.applyRootStyle(elm.getAttribute("style"));
 			_Style.Current = _Style.Root;
 		}
-		setBackgroundColor(_Style.Current.BackgroundColor);
+		applyBackground(elm);
 	}
 
 	// ***************************************************************************
@@ -6278,7 +6299,7 @@ namespace NLGUI
 		if (_Style.checkStyle("background-repeat", "1") || _Style.checkStyle("background-repeat", "repeat"))
 			_Cells.back()->setTextureTile(true);
 
-		if (_Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "cover"))
+		if (_Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "100% 100%"))
 			_Cells.back()->setTextureScale(true);
 
 		if (_Style.hasStyle("background-image"))

From 7ca3b85c5468da8c7d8c90fd862886a03a607a6c Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Sat, 4 May 2019 10:18:24 +0300
Subject: [PATCH 74/75] Changed: background shorthand parsing

--HG--
branch : develop
---
 code/nel/src/gui/css_style.cpp  | 258 ++++++++++++++++++++++++++------
 code/nel/src/gui/group_html.cpp |   4 +-
 2 files changed, 215 insertions(+), 47 deletions(-)

diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp
index 88e438870..8dcfa5deb 100644
--- a/code/nel/src/gui/css_style.cpp
+++ b/code/nel/src/gui/css_style.cpp
@@ -227,7 +227,7 @@ namespace NLGUI
 					// child of - immediate parent must match previous selector
 					if (!child->parent)
 					{
-						return false;					
+						return false;
 					}
 					child = child->parent;
 					mustMatchNext = true;
@@ -430,8 +430,8 @@ namespace NLGUI
 			}
 		}
 
-		// second pass: rest of style
-		for (it=styleRules.begin(); it != styleRules.end(); ++it)
+		// second pass: use style own StyleRules as its updated from first pass
+		for (it=style.StyleRules.begin(); it != style.StyleRules.end(); ++it)
 		{
 			if (it->first == "border" || it->first == "border-width")
 			{
@@ -456,7 +456,7 @@ namespace NLGUI
 				{
 					style.BorderWidth = 5;
 				}
-				else 
+				else
 				{
 					std::string unit;
 					if (getCssLength(tmpf, unit, it->second.c_str()))
@@ -763,7 +763,7 @@ namespace NLGUI
 				else if (it->second == "transparent")
 					style.BackgroundColorOver = CRGBA(0, 0, 0, 0);
 				else if (it->second == "currentcolor")
-					style.BackgroundColorOver = style.TextColor;	
+					style.BackgroundColorOver = style.TextColor;
 				else
 					scanHTMLColor(it->second.c_str(), style.BackgroundColorOver);
 			}
@@ -795,115 +795,278 @@ namespace NLGUI
 			"background-attachment", "background-origin", "background-clip", "background-color"};
 		std::string values[nbProps];
 		bool found[nbProps] = {false};
-
+		bool bgClipFound = false;
+		std::string bgClipValue;
+		std::string bgPositionX;
+		std::string bgPositionY;
 
 		uint partIndex = 0;
 		std::vector<std::string> parts;
 		std::vector<std::string>::iterator it;
 		// FIXME: this will fail if url() contains ' ' chars
+		// FIXME: this will also fail on 'background: rgb(255, 0, 0)'
 		NLMISC::splitString(value, " ", parts);
 
 		bool failed = false;
-		for(uint index = 0; index < parts.size(); index++)
+		bool allowSize = false;
+		uint index = 0;
+		while(!failed && index < parts.size())
 		{
-			const std::string val = toLower(trim(parts[index]));
-
+			std::string val = toLower(parts[index]);
+			bool matches = false;
 			for(uint i = 0; i < nbProps; i++)
 			{
-				if (found[i])
-				{
-					continue;
-				}
+				if (found[i]) continue;
 
 				if (props[i] == "background-image")
 				{
 					if (val.substr(0, 4) == "url(")
 					{
+						matches = true;
+						found[i] = true;
 						// use original value as 'val' is lowercase
 						values[i] = parts[index];
-						found[i] = true;
 					}
 				}
 				else if (props[i] == "background-position")
 				{
-					// TODO:
+					uint next = index;
+					bool loop = false;
+					do
+					{
+						float fval;
+						std::string unit;
+
+						// first loop -> true
+						// second loop -> false && break
+						loop = !loop;
+
+						val = toLower(parts[next]);
+						if (val == "center")
+						{
+							if (bgPositionX.empty()) bgPositionX = "center";
+							if (bgPositionY.empty()) bgPositionY = "center";
+							// consume 'center'
+							next++;
+						}
+						else if (val == "left" || val == "right")
+						{
+							bgPositionX = val;
+							// consume 'left|right'
+							next++;
+							if(next < parts.size() && getCssLength(fval, unit, parts[next]))
+							{
+								bgPositionX += " " + toString("%.0f%s", fval, unit.c_str());
+								// consume css length
+								next++;
+							}
+						}
+						else if (val == "top" || val == "bottom")
+						{
+							bgPositionY = val;
+							// consume top|bottom
+							next++;
+							if (next < parts.size() && getCssLength(fval, unit, parts[next]))
+							{
+								bgPositionY += " " + toString("%.0f%s", fval, unit.c_str());
+								// consume css length
+								next++;
+							}
+						}
+					} while (loop);
+
+					//
+					if (!bgPositionX.empty() && !bgPositionY.empty())
+					{
+						matches = true;
+						found[i] = true;
+						// consume position values if there were any
+						index = next-1;
+
+						// look ahead to see if size is next
+						if (next < parts.size() && parts[next] == "/")
+							allowSize = true;
+					}
 				}
 				else if (props[i] == "background-size")
 				{
-					// TODO: [<length-percentage> | auto ]{1,2} cover | contain
+					if (allowSize && val == "/")
+					{
+						uint next = index + 1;
+						if (next < parts.size())
+						{
+							val = toLower(parts[next]);
+							if (val == "cover" || val == "contain")
+							{
+								matches = true;
+								found[i] = true;
+								values[i] = val;
+								index = next;
+							}
+							else
+							{
+								float fval;
+								std::string unit;
+								std::string h, v;
+
+								if (val == "auto" || getCssLength(fval, unit, val))
+								{
+									if (val == "auto")
+										h = v = "auto";
+									else
+										h = v = toString("%.0f%s", fval, unit.c_str());
+
+									next++;
+									if (next < parts.size())
+									{
+										val = toLower(parts[next]);
+										if (val == "auto")
+											v = "auto";
+										else if (getCssLength(fval, unit, val))
+											v = toString("%.0f%s", fval, unit.c_str());
+										else
+											next--; // not size token
+									}
+									else
+									{
+										// not size token
+										next--;
+									}
+								}
+
+								if (!h.empty() && !v.empty())
+								{
+									matches = true;
+									found[i] = true;
+									values[i] = h + " " + v;
+									index = next;
+								}
+							}
+						}
+						else
+						{
+							// no size, just '/'
+							failed = true;
+							break;
+						}
+					}
 				}
 				else if (props[i] == "background-repeat")
 				{
 					if (val == "repeat-x" || val == "repeat-y" || val == "repeat" || val == "space" || val == "round" || val == "no-repeat")
 					{
+						matches = true;
+						found[i] = true;
+
 						if (val == "repeat-x")
 						{
 							values[i] = "repeat no-repeat";
 						}
 						else if (val == "repeat-y")
 						{
-							values[i] = "no-repeat repeat";				
+							values[i] = "no-repeat repeat";
 						}
 						else
 						{
 							std::string horiz = val;
 							std::string vert = val;
-							if (index+1 < parts.size())
+							uint next = index + 1;
+							if (next < parts.size())
 							{
-								std::string next = toLower(trim(parts[index+1]));
-								if (next == "repeat" || next == "space" || next == "round" || next == "no-repeat")
+								val = toLower(parts[next]);
+								if (val == "repeat" || val == "space" || val == "round" || val == "no-repeat")
 								{
-									vert = next;
-									index++;
+									vert = val;
+									index = next;
 								}
 							}
-							
-							values[i] = horiz + " " + vert;
+							if (vert == horiz)
+								values[i] = vert;
+							else
+								values[i] = horiz + " " + vert;
 						}
-
-						found[i] = true;
 					}
 				}
 				else if (props[i] == "background-attachment")
 				{
-					// TODO: scroll | fixed | local
+					if (val == "scroll" || val == "fixed" || val == "local")
+					{
+						matches = true;
+						found[i] = true;
+						values[i] = val;
+					}
 				}
-				else if (props[i] == "background-origin" || props[i] == "background-clip")
+				else if (props[i] == "background-origin")
 				{
-					// same values for both
 					if (val == "padding-box" || val == "border-box" || val == "content-box")
 					{
-						values[i] = val;
+						matches = true;
 						found[i] = true;
+						values[i] = val;
+
+						// first time background-origin is set, also set background-clip
+						if (!bgClipFound)
+							bgClipValue = val;
+					}
+				}
+				else if (props[i] == "background-clip")
+				{
+					if (val == "text" || val == "padding-box" || val == "border-box" || val == "content-box")
+					{
+						matches = true;
+						found[i] = true;
+						bgClipFound = true;
+						bgClipValue = val;
 					}
 				}
 				else if (props[i] == "background-color")
 				{
 					CRGBA color;
-					if (!scanHTMLColor(val.c_str(), color))
+					if (val == "transparent" || val == "currentcolor" || scanHTMLColor(val.c_str(), color))
 					{
-						failed = true;
-						break;
+						matches = true;
+						found[i] = true;
+						values[i] = val;
 					}
-					values[i] = val;
-					// color should come as last item
-					break;
 				}
+
+				// prop was found and parsed
+				if (found[i])
+					break;
 			}
+			failed = !matches;
+
+			index++;
 		}
 
 		// invalidate whole rule
 		if (failed)
 		{
-			return;
+			bgClipFound = false;
+			for(uint i = 0; i < nbProps; i++)
+			{
+				found[i] = false;
+			}
 		}
 
-		// apply found styles
+		// apply found styles or use default
 		for(uint i = 0; i < nbProps; i++)
 		{
 			if (found[i])
 			{
-				style.StyleRules[props[i]] = values[i];
+				if (props[i] == "background-position")
+				{
+					style.StyleRules["background-position-x"] = bgPositionX;
+					style.StyleRules["background-position-y"] = bgPositionY;
+				}
+				else if (props[i] == "background-clip")
+				{
+					style.StyleRules["background-clip"] = bgClipValue;
+				}
+				else
+				{
+					style.StyleRules[props[i]] = values[i];
+				}
 			}
 			else
 			{
@@ -914,27 +1077,32 @@ namespace NLGUI
 				}
 				else if (props[i] == "background-position")
 				{
-					//style.StyleRules[props[i]] = "0% 0%";
+					style.StyleRules[props[i]] = "0% 0%";
+					style.StyleRules["background-position-x"] = "left 0%";
+					style.StyleRules["background-position-y"] = "top 0%";
 				}
 				else if (props[i] == "background-size")
 				{
-					//style.StyleRules[props[i]] = "auto auto";
+					style.StyleRules[props[i]] = "auto auto";
 				}
 				else if (props[i] == "background-repeat")
 				{
-					style.StyleRules[props[i]] = "repeat repeat";
+					style.StyleRules[props[i]] = "repeat";
 				}
 				else if(props[i] == "background-attachment")
 				{
-					//style.StyleRules[props[i]] = "scroll";
+					style.StyleRules[props[i]] = "scroll";
 				}
 				else if(props[i] == "background-origin")
 				{
-					//style.StyleRules[props[i]] = "padding-box";
+					style.StyleRules[props[i]] = "padding-box";
 				}
 				else if (props[i] == "background-clip")
 				{
-					//style.StyleRules[props[i]] = "border-box";
+					if (bgClipFound)
+						style.StyleRules[props[i]] = bgClipValue;
+					else
+						style.StyleRules[props[i]] = "border-box";
 				}
 				else if (props[i] == "background-color")
 				{
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index e11369014..a6ced170f 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -3545,7 +3545,7 @@ namespace NLGUI
 				// todo handle unicode POST here
 				if (form.Entries[i].Checkbox->getPushed ())
 				{
-                                        entryData = form.Entries[i].Value;
+					entryData = form.Entries[i].Value;
 					addEntry = true;
 				}
 			}
@@ -5048,7 +5048,7 @@ namespace NLGUI
 				// TODO: else
 
 				// default background color is transparent, so image does not show
-				if (!_Style.hasStyle("background-color"))
+				if (!_Style.hasStyle("background-color") || _Style.checkStyle("background-color", "transparent"))
 				{
 					_Style.applyStyle("background-color: #fff;");
 				}

From 9444e057553066a38a1649f13f9a0c16fc82ae4d Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Sat, 4 May 2019 10:18:24 +0300
Subject: [PATCH 75/75] Changed: Normalize style values

--HG--
branch : develop
---
 code/nel/include/nel/gui/css_style.h | 12 +++-
 code/nel/src/gui/css_style.cpp       | 87 ++++++++++++++++++++++++++--
 code/nel/src/gui/group_html.cpp      | 57 ++++++------------
 3 files changed, 109 insertions(+), 47 deletions(-)

diff --git a/code/nel/include/nel/gui/css_style.h b/code/nel/include/nel/gui/css_style.h
index dea4a1f43..74fcf240d 100644
--- a/code/nel/include/nel/gui/css_style.h
+++ b/code/nel/include/nel/gui/css_style.h
@@ -47,7 +47,7 @@ namespace NLGUI
 			sint32 X;
 			sint32 Y;
 			NLMISC::CRGBA Color;
-		};		
+		};
 	public:
 		CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
 		{
@@ -110,7 +110,7 @@ namespace NLGUI
 
 			// pseudo element like ':before'
 			std::string PseudoElement;
-			
+
 			// returns selector specificity
 			uint specificity() const;
 		};
@@ -134,6 +134,12 @@ namespace NLGUI
 		void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current) const;
 		void getStyleParams(const TStyle &styleRules, CStyleParams &style, const CStyleParams &current) const;
 
+		// extract from styleRules into style.StyleRules (expand shorthand, normalize, calculate current font-size)
+		void normalize(const TStyle &styleRules, CStyleParams &style, const CStyleParams &current) const;
+
+		// apply style.StyleRyles
+		void apply(CStyleParams &style, const CStyleParams &current) const;
+
 		// merge src into dest by overwriting key in dest
 		void merge(TStyle &dst, const TStyle &src) const;
 
@@ -171,7 +177,7 @@ namespace NLGUI
 			Current.MaxWidth=-1;
 			Current.MaxHeight=-1;
 			Current.BorderWidth=1;
-			
+
 			Current.StyleRules.clear();
 		}
 
diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp
index 8dcfa5deb..0147b06f5 100644
--- a/code/nel/src/gui/css_style.cpp
+++ b/code/nel/src/gui/css_style.cpp
@@ -332,10 +332,18 @@ namespace NLGUI
 			return;
 		}
 
-		// first pass:
-		// - get font-size for 'em' sizes
-		// - split shorthand to its parts
-		// - get TextColor value that could be used for 'currentcolor'
+		normalize(styleRules, style, current);
+		apply(style, current);
+	}
+
+	// first pass
+	// - get font-size for 'em' sizes
+	// - split shorthand to its parts
+	// - get TextColor value that could be used for 'currentcolor'
+	// - normalize values
+	void CCssStyle::normalize(const TStyle &styleRules, CStyleParams &style, const CStyleParams &current) const
+	{
+		TStyle::const_iterator it;
 		for (it=styleRules.begin(); it != styleRules.end(); ++it)
 		{
 			// update local copy of applied style
@@ -407,6 +415,7 @@ namespace NLGUI
 				}
 				else
 				{
+					float tmpf;
 					std::string unit;
 					if (getCssLength(tmpf, unit, it->second.c_str()))
 					{
@@ -428,9 +437,38 @@ namespace NLGUI
 			{
 				parseBackgroundShorthand(it->second, style);
 			}
-		}
+			else
+			if (it->first == "background-repeat")
+			{
+				// old ryzom specific value
+				if (it->second == "1")
+					style.StyleRules[it->first] = "repeat";
+			}
+			else
+			if (it->first == "background-scale")
+			{
+				// replace old ryzom specific rule with background-size
+				if (it->second != "1")
+				{
+					style.StyleRules["background-size"] = "auto";
+				}
+				else
+				{
+					style.StyleRules["background-size"] = "100%";
+				}
 
-		// second pass: use style own StyleRules as its updated from first pass
+				TStyle::iterator pos = style.StyleRules.find(it->first);
+				if (pos != style.StyleRules.end())
+					style.StyleRules.erase(pos);
+			}
+		}
+	}
+
+	// apply style rules
+	void CCssStyle::apply(CStyleParams &style, const CStyleParams &current) const
+	{
+		float tmpf;
+		TStyle::const_iterator it;
 		for (it=style.StyleRules.begin(); it != style.StyleRules.end(); ++it)
 		{
 			if (it->first == "border" || it->first == "border-width")
@@ -458,6 +496,7 @@ namespace NLGUI
 				}
 				else
 				{
+					float tmpf;
 					std::string unit;
 					if (getCssLength(tmpf, unit, it->second.c_str()))
 					{
@@ -767,6 +806,42 @@ namespace NLGUI
 				else
 					scanHTMLColor(it->second.c_str(), style.BackgroundColorOver);
 			}
+			else
+			if (it->first == "background-image")
+			{
+				// normalize
+				std::string image = trim(it->second);
+				if (toLower(image.substr(0, 4)) == "url(")
+				{
+					image = image.substr(4, image.size()-5);
+				}
+				style.StyleRules[it->first] = trimQuotes(image);
+			}
+			else
+			if (it->first == "background-repeat")
+			{
+				// normalize
+				std::string val = toLower(trim(it->second));
+				std::vector<std::string> parts;
+				NLMISC::splitString(val, " ", parts);
+				// check for "repeat repeat"
+				if (parts.size() == 2 && parts[0] == parts[1])
+					val = parts[0];
+
+				style.StyleRules[it->first] = val;
+			}
+			else
+			if (it->first == "background-size")
+			{
+				// normalize
+				std::string val = toLower(trim(it->second));
+				std::vector<std::string> parts;
+				NLMISC::splitString(val, " ", parts);
+				if (parts.size() == 2 && parts[0] == parts[1])
+					val = parts[0];
+
+				style.StyleRules[it->first] = val;
+			}
 		}
 
 		// if outer element has underline set, then inner element cannot remove it
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index a6ced170f..5e0da0488 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -1220,7 +1220,7 @@ namespace NLGUI
 		{
 			std::string::size_type start;
 			std::string token;
-		
+
 			// not supported
 			// counter, open-quote, close-quote, no-open-quote, no-close-quote
 			if (content[pos] == '"' || content[pos] == '\'')
@@ -3271,9 +3271,9 @@ namespace NLGUI
 
 		setTitle(_TitleString);
 	}
-	
+
 	std::string CGroupHTML::getTitle() const {
-		return _TitleString.toUtf8(); 
+		return _TitleString.toUtf8();
 	};
 
 	// ***************************************************************************
@@ -4075,7 +4075,7 @@ namespace NLGUI
 		{
 			// clear the page
 			beginBuild();
-				
+
 			// clear previous page and state
 			removeContent();
 
@@ -4698,7 +4698,7 @@ namespace NLGUI
 			nlwarning("BUG: unable to find current element iterator from parent");
 			return;
 		}
-		
+
 		// where fragment should be moved
 		std::list<CHtmlElement>::iterator insertBefore;
 		if (_CurrentHTMLNextSibling == NULL)
@@ -5010,7 +5010,7 @@ namespace NLGUI
 				valign = _Style.Current.VerticalAlign;
 			else if (elm.hasNonEmptyAttribute("valign"))
 				valign = toLower(elm.getAttribute("valign"));
-			
+
 			if (valign == "top")
 				cellParams.VAlign = CGroupCell::Top;
 			else if (valign == "middle")
@@ -5018,7 +5018,7 @@ namespace NLGUI
 			else if (valign == "bottom")
 				cellParams.VAlign = CGroupCell::Bottom;
 		}
-		
+
 		_CellParams.push_back (cellParams);
 	}
 
@@ -5030,15 +5030,9 @@ namespace NLGUI
 		// non-empty image
 		if (_Style.hasStyle("background-image"))
 		{
-			// value '1' and 'background-scale' are ryzom only
-			bool repeat = _Style.checkStyle("background-repeat", "1") || _Style.checkStyle("background-repeat", "repeat");
-			bool scale = _Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "100% 100%");
-			std::string image = trim(_Style.getStyle("background-image"));
-			string::size_type texExt = toLower(image).find("url(");
-			if (texExt != string::npos)
-			{
-				image = image.substr(texExt+4, image.size()-texExt-5);
-			}
+			bool repeat = _Style.checkStyle("background-repeat", "repeat");
+			bool scale = _Style.checkStyle("background-size", "100%");
+			std::string image = _Style.getStyle("background-image");
 			if (!image.empty())
 			{
 				if (root)
@@ -5063,7 +5057,7 @@ namespace NLGUI
 			{
 				setBackgroundColor(bgColor);
 			}
-			// TODO: else 
+			// TODO: else
 		}
 
 	}
@@ -5369,7 +5363,7 @@ namespace NLGUI
 		{
 			newParagraph(LIBeginSpace);
 		}
-		
+
 		renderPseudoElement(":before", elm);
 	}
 
@@ -5597,7 +5591,7 @@ namespace NLGUI
 			// no 'type' attribute, or empty
 			return;
 		}
-	
+
 		// Global color flag
 		if (elm.hasAttribute("global_color"))
 			_Style.Current.GlobalColor = true;
@@ -5862,7 +5856,7 @@ namespace NLGUI
 		_ParsingLua = _TrustedDomain; // Only parse lua if TrustedDomain
 		_LuaScript.clear();
 	}
-	
+
 	void CGroupHTML::htmlLUAend(const CHtmlElement &elm)
 	{
 		if (_ParsingLua && _TrustedDomain)
@@ -6189,7 +6183,7 @@ namespace NLGUI
 		{
 			if (elm.hasNonEmptyAttribute("cellspacing"))
 				fromString(elm.getAttribute("cellspacing"), table->CellSpacing);
-			
+
 			// TODO: cssLength, horiz/vert values
 			if (_Style.hasStyle("border-spacing"))
 				fromString(_Style.getStyle("border-spacing"), table->CellSpacing);
@@ -6296,29 +6290,16 @@ namespace NLGUI
 
 		_Cells.back() = new CGroupCell(CViewBase::TCtorParam());
 
-		if (_Style.checkStyle("background-repeat", "1") || _Style.checkStyle("background-repeat", "repeat"))
+		if (_Style.checkStyle("background-repeat", "repeat"))
 			_Cells.back()->setTextureTile(true);
 
-		if (_Style.checkStyle("background-scale", "1") || _Style.checkStyle("background-size", "100% 100%"))
+		if (_Style.checkStyle("background-size", "100%"))
 			_Cells.back()->setTextureScale(true);
 
 		if (_Style.hasStyle("background-image"))
 		{
 			string image = _Style.getStyle("background-image");
-
-			string::size_type texExt = toLower(image).find("url(");
-			// Url image
-			if (texExt != string::npos)
-			{
-				// Remove url()
-				image = image.substr(4, image.size()-5);
-				addImageDownload(image, _Cells.back());
-			// Image in BNP
-			}
-			else
-			{
-				_Cells.back()->setTexture(image);
-			}
+			addImageDownload(image, _Cells.back());
 		}
 
 		if (elm.hasNonEmptyAttribute("colspan"))
@@ -6339,7 +6320,7 @@ namespace NLGUI
 			getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, _Style.getStyle("width").c_str());
 		else if (elm.hasNonEmptyAttribute("width"))
 			getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, elm.getAttribute("width").c_str());
-		
+
 		if (_Style.hasStyle("height"))
 			getPercentage (_Cells.back()->Height, temp, _Style.getStyle("height").c_str());
 		else if (elm.hasNonEmptyAttribute("height"))