summaryrefslogtreecommitdiffstats
path: root/klinkstatus/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'klinkstatus/src/utils')
-rw-r--r--klinkstatus/src/utils/Makefile.am7
-rw-r--r--klinkstatus/src/utils/mvector.h45
-rw-r--r--klinkstatus/src/utils/utils.cpp204
-rw-r--r--klinkstatus/src/utils/utils.h64
-rw-r--r--klinkstatus/src/utils/xsl.cpp437
-rw-r--r--klinkstatus/src/utils/xsl.h111
6 files changed, 868 insertions, 0 deletions
diff --git a/klinkstatus/src/utils/Makefile.am b/klinkstatus/src/utils/Makefile.am
new file mode 100644
index 00000000..0d2ba5ba
--- /dev/null
+++ b/klinkstatus/src/utils/Makefile.am
@@ -0,0 +1,7 @@
+INCLUDES = $(LIBXSLT_CFLAGS) $(all_includes)
+METASOURCES = AUTO
+libutils_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libutils.la
+noinst_HEADERS = mvector.h utils.h xsl.h
+libutils_la_SOURCES = utils.cpp xsl.cpp
+libutils_la_LIBADD = $(LIBXSLT_LIBS) $(LIBXML_LIBS)
diff --git a/klinkstatus/src/utils/mvector.h b/klinkstatus/src/utils/mvector.h
new file mode 100644
index 00000000..e48cfda3
--- /dev/null
+++ b/klinkstatus/src/utils/mvector.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Paulo Moura Guedes *
+ * moura@kdewebdev.org *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <vector>
+
+using namespace std;
+
+typedef unsigned int uint;
+
+
+template<class T>
+void append(vector<T>* const v1, vector<T> const* const v2);
+
+
+template<class T>
+void append(vector<T>* const v1, vector<T> const* const v2)
+{
+ v1->reserve(v1->size() + v2->size());
+
+ for(uint i = 0; i != v2->size(); ++i)
+ v1->push_back( (*v2)[i]);
+}
+
+
+#endif
diff --git a/klinkstatus/src/utils/utils.cpp b/klinkstatus/src/utils/utils.cpp
new file mode 100644
index 00000000..6259f8d0
--- /dev/null
+++ b/klinkstatus/src/utils/utils.cpp
@@ -0,0 +1,204 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Paulo Moura Guedes *
+ * moura@kdewebdev.org *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "utils.h"
+
+#include <qprocess.h>
+#include <qwidget.h>
+
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+
+QString htmlDocCharset[NUMBER_OF_HTML_CODES][2] = {
+
+ { "&euro;", "@" },
+ { "&#09;", "\t" },
+ { "&#10;", "\n" },
+ { "&#13;", "\r" },
+ { "&#32;", " " },
+ { "&#33;", "!" },
+ { "&#34;", "\"" },
+ { "&#35;", "#" },
+ { "&#36;", "$" },
+ { "&#37;", "%" },
+ { "&#38;", "&" },
+ { "&#39;", "'" },
+ { "&#40;", "(" },
+ { "&#41;", ")" },
+ { "&#42;", "*" },
+ { "&#43;", "+" },
+ { "&#44;", "," },
+ { "&#45;", "-" },
+ { "&#46;", "." },
+ { "&#47;", "/" },
+ // numbers....
+ { "&#58;", ":" },
+ { "&#59;", ";" },
+ { "&#60;", "<" },
+ { "&#61;", "=" },
+ { "&#62;", ">" },
+ { "&#63;", "?" },
+ { "&#64;", "@" },
+ // letters...
+ { "&#91;", "[" },
+ { "&#92;", "\\" },
+ { "&#93;", "]" },
+ { "&#94;", "^" },
+ { "&#95;", "_" },
+ { "&#96;", "`" },
+ //letters...
+ { "&#123;", "{" },
+ { "&#124;", "|" },
+ { "&#125;", "}" },
+ { "&#126;", "~" },
+ { "&#128;", "?" },
+ { "&#130;", "," },
+ { "&#131;", "?" },
+ { "&#132;", "\"" },
+ { "&#133;", "?" },
+ { "&#134;", "?" },
+ { "&#135;", "?" },
+ { "&#137;", "?" },
+ { "&#138;", "?" },
+ { "&#139;", "<" },
+ { "&#140;", "?" },
+ { "&#142;", "?" },
+ { "&#145;", "'" },
+ { "&#146;", "'" },
+ { "&#147;", "\"" },
+ { "&#148;", "\"" },
+ { "&#149;", "*" },
+ { "&#150;", "-" },
+ { "&#151;", "-" },
+ { "&#152;", "~" },
+ { "&#153;", "?" },
+ { "&#154;", "?" },
+ { "&#155;", ">" },
+ { "&#156;", "?" },
+ { "&#158;", "?" },
+ { "&#159;", "?" },
+ { "&#161;", "?" },
+ { "&#162;", "?" },
+ { "&#163;", "?" },
+ { "&#164;", "?" },
+ { "&#165;", "?" },
+ { "&#166;", "?" },
+ { "&#167;", "?" },
+ { "&#168;", "?" },
+ { "&#169;", "" },
+ { "&#170;", "?" },
+ { "&#171;", "?" },
+ { "&#172;", "?" },
+ { "&#174;", "?" },
+ { "&#175;", "?" },
+ { "&#176;", "" },
+ { "&#177;", "?" },
+ { "&#178;", "" },
+ { "&#179;", "?" },
+ { "&#180;", "?" },
+ { "&#181;", "?" },
+ { "&#182;", "?" },
+ { "&#183;", "" },
+ { "&#184;", "?" },
+ { "&#185;", "?" },
+ { "&#186;", "?" },
+ { "&#187;", "?" },
+ { "&#188;", "?" },
+ { "&#189;", "?" },
+ { "&#190;", "?" }
+
+};
+
+
+void decode(QString& url)
+{
+ if( (int)url.find('&') != -1)
+ {
+ for(int i = 0; i != NUMBER_OF_HTML_CODES; ++i)
+ {
+ int index = url.find(htmlDocCharset[i][0]);
+ if(index != - 1)
+ {
+ url.replace(htmlDocCharset[i][0], htmlDocCharset[i][1]);
+ }
+ }
+ }
+}
+/*
+void decode(string& url)
+{
+ if( (int)url.find('&') != -1)
+ {
+ for(int i = 0; i != NUMBER_OF_HTML_CODES; ++i)
+ {
+ int index = url.find(htmlDocCharset[i][0].latin1());
+ if(index != - 1)
+ {
+ int length = htmlDocCharset[i][0].length();
+ url.replace(index, length, htmlDocCharset[i][1].latin1());
+ }
+ }
+ }
+}
+*/
+int smallerUnsigned(int a, int b)
+{
+ if(a >= 0 && b >= 0)
+ {
+ if(a < b)
+ return -1;
+ else if(a > b)
+ return 1;
+ else
+ return 0;
+ }
+
+ else if(a < 0 && b < 0)
+ return 0;
+
+ else if(a < 0)
+ return 1;
+
+ else
+ return -1;
+}
+
+namespace FileManager
+{
+QString read(QString const& path)
+{
+ QFile file(path);
+
+ if(!file.open(IO_ReadOnly))
+ {
+ kdDebug() << "File " << path << " not found." << endl;
+ return QString();
+ }
+
+ QTextStream stream(&file);
+ QString fileString = stream.read();
+
+ file.close();
+
+ return fileString;
+}
+}
diff --git a/klinkstatus/src/utils/utils.h b/klinkstatus/src/utils/utils.h
new file mode 100644
index 00000000..97d81ea0
--- /dev/null
+++ b/klinkstatus/src/utils/utils.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Paulo Moura Guedes *
+ * moura@kdewebdev.org *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <kurl.h>
+#include <qstring.h>
+
+//#include <string>
+
+
+using namespace std;
+
+
+int const NUMBER_OF_HTML_CODES = 92;
+extern QString htmlDocCharset[NUMBER_OF_HTML_CODES][2];
+
+/**
+ Decode the html charset.
+ e.g.
+ decode("mail&#64;server&#46;org") => "mail@server.org"
+*/
+void decode(QString& url);
+//void decode(string& url);
+
+/**
+ Compares to integers and returns -1 if a is smaller than b,
+ 1 if b is smaller than a, and 0 if a and b are equal or both negative.
+ If one of the integers is negative and the other isn't, it is considered
+ that the positive is smaller.
+ e.g.:
+ a = 0, b = +1 => -1
+ a = +1, b = 0 => +1
+ a = -1, b = -1 => 0
+ a = +3, b = +3 => 0
+ a = +1, b = -1 => -1
+*/
+int smallerUnsigned(int a, int b);
+
+namespace FileManager
+{
+QString read(QString const& path);
+}
+
+
+#endif
diff --git a/klinkstatus/src/utils/xsl.cpp b/klinkstatus/src/utils/xsl.cpp
new file mode 100644
index 00000000..c3b13412
--- /dev/null
+++ b/klinkstatus/src/utils/xsl.cpp
@@ -0,0 +1,437 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Paulo Moura Guedes *
+ * moura@kdewebdev.org *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "xsl.h"
+
+#include <libxml/globals.h>
+#include <libxml/parser.h>
+
+// Don't try to sort the libxslt includes alphabetically!
+// transform.h _HAS_ to be after xsltInternals.h and xsltconfig.h _HAS_ to be
+// the first libxslt include or it will break the compilation on some
+// libxslt versions
+#include <libxslt/xsltconfig.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+
+// stdlib.h is required to build on Solaris
+#include <stdlib.h>
+
+#include <qregexp.h>
+#include <qsignal.h>
+#include <qstylesheet.h>
+#include <qthread.h>
+#include <qevent.h>
+#include <qmutex.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+/**
+ * @author Jason Keirstead <jason@keirstead.org>
+ *
+ * The thread class that actually performs the XSL processing.
+ * Using a thread allows async operation.
+ */
+class KopeteXSLThread : public QObject, public QThread
+{
+public:
+ /**
+ * Thread constructor
+ *
+ * @param xmlString The XML to be transformed
+ * @param xslString The XSL stylesheet we will use to transform
+ * @param target Target object to connect to for async operation
+ * @param slotCompleted Slot to fire on completion in asnc operation
+ */
+ KopeteXSLThread( const QString &xmlString, xsltStylesheetPtr xslDoc, QObject *target = 0L, const char *slotCompleted = 0L );
+
+ /**
+ * Reimplemented from QThread. Does the processing.
+ */
+ virtual void run();
+
+ /**
+ * A user event is used to get back to the UI thread to emit the completed signal
+ */
+ bool event( QEvent *event );
+
+ static QString xsltTransform( const QString &xmlString, xsltStylesheetPtr xslDoc );
+
+ /**
+ * Returns the result string
+ */
+ const QString &result()
+ { return m_resultString; };
+
+private:
+ QString m_xml;
+ xsltStylesheetPtr m_xsl;
+ QString m_resultString;
+ QObject *m_target;
+ const char *m_slotCompleted;
+ QMutex dataMutex;
+};
+
+KopeteXSLThread::KopeteXSLThread( const QString &xmlString, xsltStylesheetPtr xslDoc, QObject *target, const char *slotCompleted )
+{
+ m_xml = xmlString;
+ m_xsl = xslDoc;
+
+ m_target = target;
+ m_slotCompleted = slotCompleted;
+}
+
+void KopeteXSLThread::run()
+{
+ dataMutex.lock();
+ m_resultString = xsltTransform( m_xml, m_xsl );
+ dataMutex.unlock();
+ // get back to the main thread
+ qApp->postEvent( this, new QEvent( QEvent::User ) );
+}
+
+bool KopeteXSLThread::event( QEvent *event )
+{
+ if ( event->type() == QEvent::User )
+ {
+ dataMutex.lock();
+ if( m_target && m_slotCompleted )
+ {
+ QSignal completeSignal( m_target );
+ completeSignal.connect( m_target, m_slotCompleted );
+ completeSignal.setValue( m_resultString );
+ completeSignal.activate();
+ }
+ dataMutex.unlock();
+ delete this;
+ return true;
+ }
+ return QObject::event( event );
+}
+
+QString KopeteXSLThread::xsltTransform( const QString &xmlString, xsltStylesheetPtr styleSheet )
+{
+ // Convert QString into a C string
+ QCString xmlCString = xmlString.utf8();
+
+ QString resultString;
+ QString errorMsg;
+
+ xmlDocPtr xmlDoc = xmlParseMemory( xmlCString, xmlCString.length() );
+ if ( xmlDoc )
+ {
+ if ( styleSheet )
+ {
+ static QCString appPath( QString::fromLatin1("\"%1\"").arg( KApplication::kApplication()->dirs()->findDirs("appdata", QString::fromLatin1("styles/data") ).front() ).utf8() );
+
+ static const char* params[3] = {
+ "appdata",
+ appPath,
+ NULL
+ };
+
+ xmlDocPtr resultDoc = xsltApplyStylesheet( styleSheet, xmlDoc, params );
+ if ( resultDoc )
+ {
+ // Save the result into the QString
+ xmlChar *mem;
+ int size;
+ xmlDocDumpMemory( resultDoc, &mem, &size );
+ resultString = QString::fromUtf8( QCString( ( char * )( mem ), size + 1 ) );
+ xmlFree( mem );
+ xmlFreeDoc( resultDoc );
+ }
+ else
+ {
+ errorMsg = i18n( "Message is null." );
+ }
+ }
+ else
+ {
+ errorMsg = i18n( "The selected stylesheet is invalid." );
+ }
+
+ xmlFreeDoc( xmlDoc );
+ }
+ else
+ {
+ errorMsg = i18n( "Message could not be parsed. This is likely due to an encoding problem." );
+ }
+
+ if ( resultString.isEmpty() )
+ {
+ resultString = i18n( "<div><b>KLinkStatus encountered the following error while parsing a message:</b><br />%1</div>" ).arg( errorMsg );
+ }
+
+ #ifdef RAWXSL
+ kdDebug(23100) << k_funcinfo << resultString << endl;
+ #endif
+ return resultString;
+}
+
+class XSLTPrivate
+{
+public:
+ xmlDocPtr xslDoc;
+ xsltStylesheetPtr styleSheet;
+ unsigned int flags;
+};
+
+XSLT::XSLT( const QString &document, QObject *parent )
+ : QObject( parent ), d(new XSLTPrivate)
+{
+ d->flags = 0;
+ d->xslDoc = 0;
+ d->styleSheet = 0;
+
+ // Init Stuff
+ xmlLoadExtDtdDefaultValue = 0;
+ xmlSubstituteEntitiesDefault( 1 );
+
+ setXSLT( document );
+}
+
+XSLT::~XSLT()
+{
+ xsltFreeStylesheet( d->styleSheet );
+
+ delete d;
+}
+
+void XSLT::setXSLT( const QString &_document )
+{
+ // Search for '<kopete-i18n>' elements and feed them through i18n().
+ // After that replace the %VAR% variables with their proper XSLT counterpart.
+ //
+ // FIXME: Preprocessing the document using the QString API is fast and simple,
+ // but also error-sensitive.
+ // In fact, there are a couple of known issues with this algorithm that
+ // depend on the strings in the current styles. If these strings change
+ // they may break the parsing here.
+ //
+ // The reason I'm doing it like this is because of issues with QDOM and
+ // namespaces in earlier Qt versions. When we drop Qt 3.1.x support we
+ // should probably convert this to more accurate DOM code. - Martijn
+ //
+ // Actually, since we need to parse into a libxml2 document anyway, this whole
+ // nonsense could be replaced with some simple XPath expressions - JK
+ //
+ QRegExp elementMatch( QString::fromLatin1( "<kopete-i18n>(.*)</kopete-i18n>" ) );
+ elementMatch.setMinimal( true );
+ QString document = _document;
+ int pos;
+ while ( ( pos = elementMatch.search( document ) ) != -1 )
+ {
+ QString orig = elementMatch.cap( 1 );
+ //kdDebug( 14010 ) << k_funcinfo << "Original text: " << orig << endl;
+
+ // Split on % and go over all parts
+ // WARNING: If you change the translator comment, also change it in the
+ // styles/extracti18n Perl script, because the strings have to be
+ // identical!
+ QStringList parts = QStringList::split( '%', i18n(
+ "Translators: The %FOO% placeholders are variables that are substituted "
+ "in the code, please leave them untranslated", orig.utf8() ), true );
+
+ // The first part is always text, as our variables are written like %FOO%
+ QStringList::Iterator it = parts.begin();
+ QString trans = *it;
+ bool prependPercent = true;
+ it = parts.remove( it );
+ for ( it = parts.begin(); it != parts.end(); ++it )
+ {
+ prependPercent = false;
+
+ if ( *it == QString::fromLatin1( "TIME" ) )
+ {
+ trans += QString::fromLatin1( "<xsl:value-of select=\"@time\"/>" );
+ }
+ else if ( *it == QString::fromLatin1( "TIMESTAMP" ) )
+ {
+ trans += QString::fromLatin1( "<xsl:value-of select=\"@timestamp\"/>" );
+ }
+ else if ( *it == QString::fromLatin1( "FORMATTEDTIMESTAMP" ) )
+ {
+ trans += QString::fromLatin1( "<xsl:value-of select=\"@formattedTimestamp\"/>" );
+ }
+ else if ( *it == QString::fromLatin1( "FROM_CONTACT_DISPLAYNAME" ) )
+ {
+ trans += QString::fromLatin1( "<span><xsl:attribute name=\"title\">"
+ "<xsl:choose>"
+ "<xsl:when test='from/contact/@contactId=from/contact/contactDisplayName/@text'>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"from/contact/metaContactDisplayName/@text\"/>"
+ "</xsl:when>"
+ "<xsl:otherwise>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"from/contact/metaContactDisplayName/@text\"/>&#160;"
+ "(<xsl:value-of disable-output-escaping=\"yes\" select=\"from/contact/@contactId\"/>)"
+ "</xsl:otherwise>"
+ "</xsl:choose></xsl:attribute>"
+ "<xsl:attribute name=\"dir\">"
+ "<xsl:value-of select=\"from/contact/contactDisplayName/@dir\"/>"
+ "</xsl:attribute>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"from/contact/contactDisplayName/@text\"/></span>" );
+ }
+ else if ( *it == QString::fromLatin1( "TO_CONTACT_DISPLAYNAME" ) )
+ {
+ trans += QString::fromLatin1( "<span><xsl:attribute name=\"title\">"
+ "<xsl:choose>"
+ "<xsl:when test='to/contact/@contactId=from/contact/contactDisplayName/@text'>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"to/contact/metaContactDisplayName/@text\"/>"
+ "</xsl:when>"
+ "<xsl:otherwise>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"to/contact/metaContactDisplayName/@text\"/>&#160;"
+ "(<xsl:value-of disable-output-escaping=\"yes\" select=\"to/contact/@contactId\"/>)"
+ "</xsl:otherwise>"
+ "</xsl:choose></xsl:attribute>"
+ "<xsl:attribute name=\"dir\">"
+ "<xsl:value-of select=\"to/contact/contactDisplayName/@dir\"/>"
+ "</xsl:attribute>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"to/contact/contactDisplayName/@text\"/></span>" );
+ }
+ else if ( *it == QString::fromLatin1( "FROM_METACONTACT_DISPLAYNAME" ) )
+ {
+ trans += QString::fromLatin1( "<span>"
+ "<xsl:attribute name=\"dir\">"
+ "<xsl:value-of select=\"from/contact/metaContactDisplayName/@dir\"/>"
+ "</xsl:attribute>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"from/contact/metaContactDisplayName/@text\"/></span>" );
+ }
+ else if ( *it == QString::fromLatin1( "TO_METACONTACT_DISPLAYNAME" ) )
+ {
+ trans += QString::fromLatin1( "<span>"
+ "<xsl:attribute name=\"dir\">"
+ "<xsl:value-of select=\"to/contact/metaContactDisplayName/@dir\"/>"
+ "</xsl:attribute>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"to/contact/metaContactDisplayName/@text\"/></span>" );
+ }
+ else if ( *it == QString::fromLatin1( "FROM_CONTACT_ID" ) )
+ {
+ trans += QString::fromLatin1( "<span><xsl:attribute name=\"title\">"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"from/contact/contactDisplayName/@text\"/></xsl:attribute>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"from/contact/@contactId\"/></span>" );
+ }
+ else if ( *it == QString::fromLatin1( "TO_CONTACT_ID" ) )
+ {
+ trans += QString::fromLatin1( "<span><xsl:attribute name=\"title\">"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"to/contact/contactDisplayName/@text\"/></xsl:attribute>"
+ "<xsl:value-of disable-output-escaping=\"yes\" select=\"to/contact/@contactId\"/></span>" );
+ }
+ else if ( *it == QString::fromLatin1( "BODY" ) )
+ {
+ trans += QString::fromLatin1( "<xsl:value-of disable-output-escaping=\"yes\" select=\"body\"/>" );
+ }
+ else
+ {
+ if ( prependPercent )
+ trans += '%';
+ trans += *it;
+ prependPercent = true;
+ }
+ }
+ //kdDebug( 14010 ) << k_funcinfo << "Translated text: " << trans << endl;
+ // Add "<kopete-i18n>" and "</kopete-i18n>" to length, hence the '+ 27'
+ document.replace( uint( pos ), orig.length() + 27, trans );
+ }
+
+ #ifdef RAWXSL
+ kdDebug(14000) << k_funcinfo << document.utf8() << endl;
+ #endif
+
+ //Freeing the stylesheet also frees the doc pointer;
+ xsltFreeStylesheet( d->styleSheet );
+ d->styleSheet = 0;
+ d->xslDoc = 0;
+ d->flags = 0;
+
+ QCString rawDocument = document.utf8();
+ d->xslDoc = xmlParseMemory( rawDocument, rawDocument.length() );
+
+ if( d->xslDoc )
+ {
+ d->styleSheet = xsltParseStylesheetDoc( d->xslDoc );
+ if( d->styleSheet )
+ {
+ // Check for flags
+ QStringList flags;
+ for( xmlNodePtr child = d->xslDoc->children; child != d->xslDoc->last; child = child->next )
+ {
+ if( child->type == XML_PI_NODE )
+ {
+ //We have a flag. Enable it;
+ QCString flagData( (const char*)child->content );
+
+ if( flagData.contains( "Flag:" ) )
+ {
+ flags += flagData.mid(5);
+ }
+ }
+ }
+
+ if( !flags.isEmpty() )
+ setProperty("flags", flags.join( QString::fromLatin1("|") ) );
+ }
+ else
+ {
+ kdWarning(14000) << "Invalid stylesheet provided" << endl;
+
+ //We don't have a stylesheet, so free the doc pointer
+ xmlFreeDoc( d->xslDoc );
+ d->styleSheet = 0;
+ d->xslDoc = 0;
+ }
+ }
+ else
+ {
+ kdWarning(14000) << "Invalid stylesheet provided" << endl;
+ d->xslDoc = 0;
+ }
+}
+
+QString XSLT::transform( const QString &xmlString )
+{
+ return KopeteXSLThread::xsltTransform( xmlString, d->styleSheet );
+}
+
+void XSLT::transformAsync( const QString &xmlString, QObject *target, const char *slotCompleted )
+{
+ ( new KopeteXSLThread( xmlString, d->styleSheet, target, slotCompleted ) )->start();
+}
+
+bool XSLT::isValid() const
+{
+ return d->styleSheet != NULL;
+}
+
+void XSLT::setFlags( unsigned int flags )
+{
+ d->flags = flags;
+}
+
+unsigned int XSLT::flags() const
+{
+ return d->flags;
+}
+
+#include "xsl.moc"
+
+// vim: set noet ts=4 sts=4 sw=4:
+
diff --git a/klinkstatus/src/utils/xsl.h b/klinkstatus/src/utils/xsl.h
new file mode 100644
index 00000000..9d12c1c1
--- /dev/null
+++ b/klinkstatus/src/utils/xsl.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Paulo Moura Guedes *
+ * moura@kdewebdev.org *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef XSL_H
+#define XSL_H
+
+#include <qobject.h>
+
+class XSLTPrivate;
+
+/**
+ @author Paulo Moura Guedes <moura@kdewebdev.org>
+
+ Taken from kopetexsl. Kudos to the Kopete team.
+ *
+ * This class provides an easy to use interface to basic
+ * libxslt transformations.
+*/
+class XSLT : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY( Flags flags READ flags WRITE setFlags )
+ Q_PROPERTY( bool isValid READ isValid )
+
+ Q_SETS( Flags )
+
+public:
+ /**
+ * Special flags to be used during the transformation process. Passed
+ * into the engine as processing instructions.
+ */
+ enum Flags
+ {
+ TransformAllMessages = 1
+ };
+
+ /**
+ * Constructor.
+ *
+ * Constructs a new XSLT parser using the provided XSLT document
+ */
+ XSLT( const QString &xsltDocument, QObject *parent = 0L );
+
+ virtual ~XSLT();
+
+ /**
+ * Set the XSLT document
+ *
+ * @return an ORed set of @ref Flags, or 0 if none
+ */
+ void setXSLT( const QString &document );
+
+ /**
+ * Transforms the XML string using the XSLT document, synchronously
+ *
+ * @param xmlString The source XML
+ * @return The result of the transformation
+ */
+ QString transform( const QString &xmlString );
+
+ /**
+ * Transforms the XML string using the XSLT document, asynchronously
+ *
+ * @param xmlString The source XML
+ * @param target The QObject that contains the slot to be executed when processing is complete
+ * @param slotCompleted A slot that accepts a QVariant & paramater, that is the result
+ * of the transformation
+ */
+ void transformAsync( const QString &xmlString, QObject *target, const char *slotCompleted );
+
+ /**
+ * Check whether the XSLT document is valid
+ *
+ * @return Whether the document represents a valid XSLT stylesheet
+ */
+ bool isValid() const;
+
+ /**
+ * @return An ORed list of Flags that the current stylesheet provides via processing instructions
+ */
+ unsigned int flags() const;
+
+ /**
+ * Sets flags to be used for the transformation.
+ *
+ * @param flags An ORed list of flags
+ */
+ void setFlags( unsigned int flags );
+
+private:
+ XSLTPrivate *d;
+};
+
+#endif