added missed sources

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5.0@2895 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
defnax 2010-05-13 15:36:49 +00:00
parent acbcf57bd8
commit 76250a956b
2 changed files with 236 additions and 0 deletions

View File

@ -0,0 +1,124 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2010, Thomas Kister
*
* 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 "HandleRichText.h"
namespace RsChat {
void EmbedInHtmlImg::InitFromAwkwardHash(const QHash< QString, QString >& hash)
{
QString newRE;
for(QHash<QString,QString>::const_iterator it = hash.begin(); it != hash.end(); ++it)
foreach(QString smile, it.key().split("|")) {
smileys.insert(smile, it.value());
newRE += "(" + QRegExp::escape(smile) + ")|";
}
newRE.chop(1); // remove last |
myRE.setPattern(newRE);
}
/**
* Parses a DOM tree and replaces text by HTML tags.
* The tree is traversed depth-first, but only through children of Element type
* nodes. Any other kind of node is terminal.
*
* If the node is of type Text, its data is checked against the user-provided
* regular expression. If there is a match, the text is cut in three parts: the
* preceding part that will be inserted before, the part to be replaced, and the
* following part which will be itself checked against the regular expression.
*
* The part to be replaced is sent to a user-provided functor that will create
* the necessary embedding and return a new Element node to be inserted.
*
* @param[in] doc The whole DOM tree, necessary to create new nodes
* @param[in,out] currentElement The current node (which is of type Element)
* @param[in] embedInfos The regular expression and the type of embedding to use
*/
void embedHtml(QDomDocument& doc, QDomElement& currentElement, const EmbedInHtml& embedInfos)
{
if(embedInfos.myRE.pattern().length() == 0) // we'll get stuck with an empty regexp
return;
QDomNodeList children = currentElement.childNodes();
for(uint index = 0; index < children.length(); index++) {
QDomNode tempNode = children.item(index);
if(tempNode.isElement()) {
// child is an element, we skip it if it's an <a> tag
QDomElement tempElement = tempNode.toElement();
if(tempElement.tagName().toLower() != "head" && tempElement.tagName().toLower() != "a")
embedHtml(doc, tempElement, embedInfos);
}
else if(tempNode.isText()) {
// child is a text, we parse it
QString tempText = tempNode.toText().data();
if(embedInfos.myRE.indexIn(tempText) == -1)
continue;
// there is at least one link inside, we start replacing
int currentPos = 0;
int nextPos = 0;
while((nextPos = embedInfos.myRE.indexIn(tempText, currentPos)) != -1) {
// if nextPos == 0 it means the text begins by a link
if(nextPos > 0) {
QDomText textPart = doc.createTextNode(tempText.mid(currentPos, nextPos - currentPos));
currentElement.insertBefore(textPart, tempNode);
index++;
}
// inserted tag
QDomElement insertedTag;
switch(embedInfos.myType) {
case Ahref: insertedTag = doc.createElement("a");
insertedTag.setAttribute("href", embedInfos.myRE.cap(0));
insertedTag.appendChild(doc.createTextNode(embedInfos.myRE.cap(0)));
break;
case Img: insertedTag = doc.createElement("img");
{
const EmbedInHtmlImg& embedImg = static_cast<const EmbedInHtmlImg&>(embedInfos);
insertedTag.setAttribute("src", embedImg.smileys[embedInfos.myRE.cap(0)]);
}
break;
}
currentElement.insertBefore(insertedTag, tempNode);
currentPos = nextPos + embedInfos.myRE.matchedLength();
index++;
}
// text after the last link, only if there's one, don't touch the index
// otherwise decrement the index because we're going to remove tempNode
if(currentPos < tempText.length()) {
QDomText textPart = doc.createTextNode(tempText.mid(currentPos));
currentElement.insertBefore(textPart, tempNode);
}
else
index--;
currentElement.removeChild(tempNode);
}
}
}
} // namespace RsChat

View File

@ -0,0 +1,112 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2010, Thomas Kister
*
* 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.
****************************************************************/
/**
* This file provides helper functions and functors for translating data from/to
* rich text format and HTML. Its main goal is to facilitate decoding of chat
* messages, particularly embedding special information into HTML tags.
*/
#ifndef HANDLE_RICH_TEXT_H_
#define HANDLE_RICH_TEXT_H_
#include <QRegExp>
#include <QtXml>
namespace RsChat {
/**
* The type of embedding we'd like to do
*/
enum EmbeddedType
{
Ahref, ///< into <a></a>
Img, ///< into <img/>
};
/**
* Base class for storing information about a given kind of embedding.
*
* Its only constructor is protected so it is impossible to instantiate it, and
* at the same time derived classes have to provide a type.
*/
class EmbedInHtml
{
protected:
EmbedInHtml(EmbeddedType newType) :
myType(newType)
{}
public:
const EmbeddedType myType;
QRegExp myRE;
};
/**
* This class is used to store information for embedding links into <a></a> tags.
*/
class EmbedInHtmlAhref : public EmbedInHtml
{
public:
EmbedInHtmlAhref() :
EmbedInHtml(Ahref)
{
myRE.setPattern("(\\bretroshare://[^\\s]*)|(\\bhttps?://[^\\s]*)|(\\bwww\\.[^\\s]*)");
}
};
/**
* This class is used to store information for embedding smileys into <img/> tags.
*
* By default the QRegExp the variables are empty, which means it must be
* filled at runtime, typically when the smileys set is loaded. It can be
* either done by hand or by using one of the helper methods available.
*
* Note: The QHash uses only *one* smiley per key (unlike soon-to-be-upgraded
* code out there).
*/
class EmbedInHtmlImg : public EmbedInHtml
{
public:
EmbedInHtmlImg() :
EmbedInHtml(Img)
{}
void InitFromAwkwardHash(const QHash<QString,QString>& hash);
QHash<QString,QString> smileys;
};
void embedHtml(QDomDocument& doc, QDomElement& currentElement, const EmbedInHtml& embedInfos);
} // namespace RsChat
#endif // HANDLE_RICH_TEXT_H_