summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/gadu/gadurichtextformat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/gadu/gadurichtextformat.cpp')
-rw-r--r--kopete/protocols/gadu/gadurichtextformat.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/kopete/protocols/gadu/gadurichtextformat.cpp b/kopete/protocols/gadu/gadurichtextformat.cpp
new file mode 100644
index 00000000..a93b95fd
--- /dev/null
+++ b/kopete/protocols/gadu/gadurichtextformat.cpp
@@ -0,0 +1,291 @@
+// -*- Mode: c++-mode; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 2; -*-
+//
+// Copyright (C) 2004 Grzegorz Jaskiewicz <gj at pointblue.com.pl>
+//
+// gadurichtextformat.cpp
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+
+#include <knotifyclient.h>
+#include <kdebug.h>
+#include <kopetemessage.h>
+
+#include "gadurichtextformat.h"
+#include "gadusession.h"
+
+#include <qstring.h>
+#include <qregexp.h>
+
+GaduRichTextFormat::GaduRichTextFormat()
+{
+}
+
+GaduRichTextFormat::~GaduRichTextFormat()
+{
+}
+
+QString
+GaduRichTextFormat::convertToHtml( const QString& msg, unsigned int formats, void* formatStructure)
+{
+ QString tmp, nb;
+ gg_msg_richtext_format *format;
+ char *pointer = (char*) formatStructure;
+
+ unsigned int i,j;
+ int r, g, b;
+ r = g = b = 0;
+ bool opened = false;
+
+ if ( formatStructure == NULL || formats == 0 ) {
+ tmp = msg;
+ escapeBody( tmp );
+ return tmp;
+ }
+
+ for ( i = 0, j = 0 ; i < formats ; ) {
+ format = (gg_msg_richtext_format*) pointer;
+ unsigned int position = format->position;
+ char font = format->font;
+ QString style;
+
+ if ( position < j || position > msg.length() ) {
+ break;
+ }
+
+ if ( font & GG_FONT_IMAGE ) {
+ i += sizeof( gg_msg_richtext_image );
+ pointer += sizeof( gg_msg_richtext_image );
+ tmp += "<b>[this should be a picture, not yet implemented]</b>";
+ }
+ else {
+ nb = msg.mid( j, position - j );
+ tmp += escapeBody( nb );
+
+ j = position;
+
+ // add message bit between formating
+ if ( opened ) {
+ tmp += formatClosingTag("span");
+ opened = false;
+ }
+ // set font attributes
+ if ( font & GG_FONT_BOLD ) {
+ style += (" font-weight:bold; ");
+ }
+ if ( font & GG_FONT_ITALIC ) {
+ style += (" font-style:italic; ");
+ }
+ if ( font & GG_FONT_UNDERLINE ) {
+ style += (" text-decoration:underline; ");
+ }
+ // add color
+ if ( font & GG_FONT_COLOR ) {
+ pointer += sizeof( gg_msg_richtext_format );
+ i += sizeof( gg_msg_richtext_format );
+ gg_msg_richtext_color *color = (gg_msg_richtext_color*)( pointer );
+ r = (int)color->red;
+ g = (int)color->green;
+ b = (int)color->blue;
+ }
+ style += QString(" color: rgb( %1, %2, %3 ); ").arg( r ).arg( g ).arg( b );
+
+ tmp += formatOpeningTag( QString::fromLatin1("span"), QString::fromLatin1("style=\"%1\"").arg( style ) );
+ opened = true;
+
+ }
+
+ // advance to next structure in row
+ pointer += sizeof( gg_msg_richtext_format );
+ i += sizeof( gg_msg_richtext_format );
+ }
+
+ nb = msg.mid( j, msg.length() );
+ tmp += escapeBody( nb );
+ if ( opened ) {
+ tmp += formatClosingTag("span");
+ }
+
+ return tmp;
+}
+
+QString
+GaduRichTextFormat::formatOpeningTag( const QString& tag, const QString& attributes )
+{
+ QString res = "<" + tag;
+ if(!attributes.isEmpty())
+ res.append(" " + attributes);
+ return res + ">";
+}
+
+QString
+GaduRichTextFormat::formatClosingTag( const QString& tag )
+{
+ return "</" + tag + ">";
+}
+
+// the initial idea stolen from IRC plugin
+KGaduMessage*
+GaduRichTextFormat::convertToGaduMessage( const Kopete::Message& message )
+{
+ QString htmlString = message.escapedBody();
+ KGaduMessage* output = new KGaduMessage;
+ rtcs.blue = rtcs.green = rtcs.red = 0;
+ color = QColor();
+ int position = 0;
+
+ rtf.resize( sizeof( gg_msg_richtext) );
+ output->rtf.resize(0);
+
+ // test first if there is any HTML formating in it
+ if( htmlString.find( QString::fromLatin1("</span") ) > -1 ) {
+ QRegExp findTags( QString::fromLatin1("<span style=\"(.*)\">(.*)</span>") );
+ findTags.setMinimal( true );
+ int pos = 0;
+ int lastpos = 0;
+
+ while ( pos >= 0 ){
+ pos = findTags.search( htmlString );
+ rtfs.font = 0;
+ if ( pos != lastpos ) {
+ QString tmp;
+ if ( pos < 0 ) {
+ tmp = htmlString.mid( lastpos );
+ }
+ else {
+ tmp = htmlString.mid( lastpos, pos - lastpos );
+ }
+ if ( !tmp.isEmpty() ) {
+ color.setRgb( 0, 0, 0 );
+ if ( insertRtf( position ) == false ) {
+ delete output;
+ return NULL;
+ }
+ tmp = unescapeGaduMessage( tmp );
+ output->message += tmp;
+ position += tmp.length();
+ }
+ }
+
+ if ( pos > -1 ) {
+ QString styleHTML = findTags.cap(1);
+ QString replacement = findTags.cap(2);
+ QStringList styleAttrs = QStringList::split( ';', styleHTML );
+ rtfs.font = 0;
+
+ lastpos = pos + replacement.length();
+
+ for( QStringList::Iterator attrPair = styleAttrs.begin(); attrPair != styleAttrs.end(); ++attrPair ) {
+ QString attribute = (*attrPair).section(':',0,0);
+ QString value = (*attrPair).section(':',1);
+ parseAttributes( attribute, value );
+ }
+
+ if ( insertRtf( position ) == false ) {
+ delete output;
+ return NULL;
+ }
+
+ QString rep = QString("<span style=\"%1\">%2</span>" ).arg( styleHTML ).arg( replacement );
+ htmlString.replace( findTags.pos( 0 ), rep.length(), replacement );
+
+ replacement = unescapeGaduMessage( replacement );
+ output->message += replacement;
+ position += replacement.length();
+ }
+
+ }
+ output->rtf = rtf;
+ // this is sick, but that's the way libgadu is designed
+ // here I am adding network header !, should sit in libgadu IMO
+ header = (gg_msg_richtext*) output->rtf.data();
+ header->length = output->rtf.size() - sizeof( gg_msg_richtext );
+ header->flag = 2;
+ }
+ else {
+ output->message = message.escapedBody();
+ output->message = unescapeGaduMessage( output->message );
+ }
+
+ return output;
+
+}
+
+void
+GaduRichTextFormat::parseAttributes( const QString attribute, const QString value )
+{
+ if( attribute == QString::fromLatin1("color") ) {
+ color.setNamedColor( value );
+ }
+ if( attribute == QString::fromLatin1("font-weight") && value == QString::fromLatin1("600") ) {
+ rtfs.font |= GG_FONT_BOLD;
+ }
+ if( attribute == QString::fromLatin1("text-decoration") && value == QString::fromLatin1("underline") ) {
+ rtfs.font |= GG_FONT_UNDERLINE ;
+ }
+ if( attribute == QString::fromLatin1("font-style") && value == QString::fromLatin1("italic") ) {
+ rtfs.font |= GG_FONT_ITALIC;
+ }
+}
+
+QString
+GaduRichTextFormat::unescapeGaduMessage( QString& ns )
+{
+ QString s;
+ s = Kopete::Message::unescape( ns );
+ s.replace( QString::fromAscii( "\n" ), QString::fromAscii( "\r\n" ) );
+ return s;
+}
+
+bool
+GaduRichTextFormat::insertRtf( uint position)
+{
+ if ( color != QColor( rtcs.red, rtcs.green, rtcs.blue ) ) {
+ rtcs.red = color.red();
+ rtcs.green = color.green();
+ rtcs.blue = color.blue();
+ rtfs.font |= GG_FONT_COLOR;
+ }
+
+ if ( rtfs.font ) {
+ // append font description
+ rtfs.position = position;
+ uint csize = rtf.size();
+ if ( rtf.resize( csize + sizeof( gg_msg_richtext_format ) ) == FALSE ) {
+ return false;
+ };
+ memcpy( rtf.data() + csize, &rtfs, sizeof( rtfs ) );
+ // append color description, if color has changed
+ if ( rtfs.font & GG_FONT_COLOR ) {
+ csize = rtf.size();
+ if ( rtf.resize( csize + sizeof( gg_msg_richtext_color ) ) == FALSE ) {
+ return false;
+ };
+ memcpy( rtf.data() + csize, &rtcs, sizeof( rtcs ) );
+ }
+ }
+ return true;
+}
+
+QString
+GaduRichTextFormat::escapeBody( QString& input )
+{
+ input.replace( '<', QString::fromLatin1("&lt;") );
+ input.replace( '>', QString::fromLatin1("&gt;") );
+ input.replace( '\n', QString::fromLatin1( "<br />" ) );
+ input.replace( '\t', QString::fromLatin1( "&nbsp;&nbsp;&nbsp;&nbsp;" ) );
+ input.replace( QRegExp( QString::fromLatin1( "\\s\\s" ) ), QString::fromLatin1( " &nbsp;" ) );
+ return input;
+}