← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2847: convert HTML colors to RTF

 

------------------------------------------------------------
revno: 2847
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Wed 2012-02-01 20:04:48 +0100
message:
  convert HTML colors to RTF
modified:
  win32/AspectChat.h
  win32/HtmlToRtf.cpp
  win32/HtmlToRtf.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'win32/AspectChat.h'
--- win32/AspectChat.h	2012-02-01 16:26:37 +0000
+++ win32/AspectChat.h	2012-02-01 19:04:48 +0000
@@ -78,17 +78,17 @@
 		tstring pre;
 		if(chat->length() > 0)
 			pre += _T("\r\n");
-		return Text::toT("{\\urtf1\n") + chat->rtfEscape(pre + message) + Text::toT("}\n");
+		return Text::toT("{\\urtf1\n") + dwt::RichTextBox::rtfEscape(pre) + message + Text::toT("}\n");
 	}
 
 public:
 	void addChat(const tstring& message) {
-		chat->addTextSteady(formatText(message));
+		chat->addTextSteady(formatText(dwt::RichTextBox::rtfEscape(message)));
 		t().addedChat(message);
 	}
 
 	void addChat(const ChatMessage& message) {
-		chat->addTextSteady(formatText(Text::toT(HtmlToRtf::convert(message.htmlMessage))));
+		chat->addTextSteady(formatText(HtmlToRtf::convert(message.htmlMessage)));
 		t().addedChat(Text::toT(message.message));
 	}
 
@@ -117,7 +117,7 @@
 
 		const size_t linesCount = lines.size();
 		for(size_t i = (linesCount > setting) ? (linesCount - setting) : 0; i < linesCount; ++i) {
-			addChat(chat->rtfEscape(_T("- ") + Text::toT(lines[i])));
+			addChat(_T("- ") + Text::toT(lines[i]));
 		}
 	}
 

=== modified file 'win32/HtmlToRtf.cpp'
--- win32/HtmlToRtf.cpp	2012-02-01 16:54:41 +0000
+++ win32/HtmlToRtf.cpp	2012-02-01 19:04:48 +0000
@@ -16,18 +16,18 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+// inspired by Bjarke Viksoe's Simple HTML Viewer <http://www.viksoe.dk/code/simplehtmlviewer.htm>.
+
 #include "stdafx.h"
 #include "HtmlToRtf.h"
 
+#include <dcpp/debug.h>
 #include <dcpp/SimpleXML.h>
+#include <dcpp/Text.h>
+
+#include <dwt/widgets/RichTextBox.h>
 
 #ifdef TODO
-namespace { tstring toRTF(COLORREF color) {
-	return Text::toT("\\red" + Util::toString(GetRValue(color)) +
-		"\\green" + Util::toString(GetGValue(color)) +
-		"\\blue" + Util::toString(GetBValue(color)) + ";");
-} }
-
 HubFrame::FormattedChatMessage HubFrame::format(const ChatMessage& message, int* pmInfo) const {
 	if(!nick.empty()) {
 		nick = chat->rtfEscape(nick);
@@ -56,41 +56,120 @@
 		}
 		ret.second += message.thirdPerson ? _T("* ") + nick + _T(" ") : _T("<") + nick + _T("> ");
 	}
-
-	auto tmp = Text::toT(Text::toDOS(text));
-	ret.first += tmp;
-	ret.second += chat->rtfEscape(tmp);
 }
 #endif
 
 struct Parser : SimpleXMLReader::CallBack {
-	Parser() { }
+	Parser() : colorIndex(0) { }
 	void startTag(const string& name, StringPairList& attribs, bool simple);
 	void endTag(const string& name, const string& data);
-	string finalize();
+	tstring finalize();
 private:
-	string ret;
+	void parseColor(const char* rtfCode, const string& s);
+	tstring ret;
+	string fonts;
+	string colors;
+	size_t colorIndex;
+	string header;
 };
 
-string HtmlToRtf::convert(const string& html) {
+tstring HtmlToRtf::convert(const string& html) {
 	Parser parser;
 	try { SimpleXMLReader(&parser).parse(html); }
-	catch(const SimpleXMLException& e) { return e.getError(); }
+	catch(const SimpleXMLException& e) { return Text::toT(e.getError()); }
 	return parser.finalize();
 }
 
 static const string styleAttr = "style";
+static const string fontStyle = "font";
+static const string textColorStyle = "color";
+static const string bgColorStyle = "background-color";
+static string tmp;
 
 void Parser::startTag(const string& name, StringPairList& attribs, bool simple) {
-	if(!attribs.empty()) {
-		const auto& style = getAttrib(attribs, styleAttr, 0);
+	if(attribs.empty()) {
+		return;
+	}
+
+	const auto& style = getAttrib(attribs, styleAttr, 0);
+
+	enum { Declaration, Font, TextColor, BgColor } state = Declaration;
+
+	size_t i = 0, j;
+	while((j = style.find_first_of(":;", i)) != string::npos) {
+		tmp = style.substr(i, j - i);
+		i = j + 1;
+
+		switch(state) {
+		case Declaration:
+			{
+				if(tmp == fontStyle) { state = Font; }
+				else if(tmp == textColorStyle) { state = TextColor; }
+				else if(tmp == bgColorStyle) { state = BgColor; }
+				break;
+			}
+
+		case Font:
+			{
+				state = Declaration;
+				break;
+			}
+
+		case TextColor:
+			{
+				parseColor("\\cf", tmp);
+				state = Declaration;
+				break;
+			}
+
+		case BgColor:
+			{
+				parseColor("\\highlight", tmp);
+				state = Declaration;
+				break;
+			}
+
+		default:
+			{
+				// unknown style
+				state = Declaration;
+				break;
+			}
+		}
 	}
 }
 
 void Parser::endTag(const string& name, const string& data) {
-	ret += data;
-}
-
-string Parser::finalize() {
-	return ret;
+	if(header.empty()) {
+		// no new RTF enclosing; write directly.
+		ret += dwt::RichTextBox::rtfEscape(Text::toT(Text::toDOS(data)));
+
+	} else {
+		ret += _T("{") + Text::toT(header) + _T(" ") + dwt::RichTextBox::rtfEscape(Text::toT(Text::toDOS(data))) + _T("}");
+		header.clear();
+	}
+}
+
+tstring Parser::finalize() {
+	if(fonts.empty() && colors.empty()) {
+		// no new RTF enclosing; write directly.
+		return ret;
+	}
+
+	return _T("{") + Text::toT(fonts + "{\\colortbl" + colors + "}") + ret + _T("}");
+}
+
+void Parser::parseColor(const char* rtfCode, const string& s) {
+	auto sharp = s.find('#');
+	if(sharp != string::npos && s.size() > sharp + 6) {
+		try {
+			size_t pos = 0;
+			auto color = std::stol(s.substr(sharp + 1, 6), &pos, 16);
+			colors += "\\red" + Util::toString((color & 0xFF0000) >> 16) +
+				"\\green" + Util::toString((color & 0xFF00) >> 8) +
+				"\\blue" + Util::toString(color & 0xFF) + ";";
+			header += rtfCode;
+			header += Util::toString(colorIndex++);
+		} catch(const std::exception& e) { dcdebug("color parsing exception: %s with str: %s\n", e.what(), s.c_str()); }
+	}
 }

=== modified file 'win32/HtmlToRtf.h'
--- win32/HtmlToRtf.h	2012-02-01 16:26:37 +0000
+++ win32/HtmlToRtf.h	2012-02-01 19:04:48 +0000
@@ -24,7 +24,7 @@
 supported. */
 class HtmlToRtf {
 public:
-	static string convert(const string& html);
+	static tstring convert(const string& html);
 };
 
 #endif