23#include "linklocator.h"
24#include "pimemoticons.h"
26#include <kstandarddirs.h>
27#include <kstaticdeleter.h>
31#include <tqstylesheet.h>
37TQMap<TQString, TQString> *LinkLocator::s_smileyEmoticonNameMap = 0;
38TQMap<TQString, TQString> *LinkLocator::s_smileyEmoticonHTMLCache = 0;
40static KStaticDeleter< TQMap<TQString, TQString> > smileyMapDeleter;
41static KStaticDeleter< TQMap<TQString, TQString> > smileyCacheDeleter;
44 :
mText(text),
mPos(pos), mMaxUrlLen(4096), mMaxAddressLen(255)
52 if ( !s_smileyEmoticonNameMap ) {
53 smileyMapDeleter.setObject( s_smileyEmoticonNameMap,
54 new TQMap<TQString, TQString>() );
55 for (
int i = 0; i < EmotIcons::EnumSindex::COUNT; ++i ) {
56 TQString imageName( EmotIcons::EnumSindex::enumToString[i] );
57 imageName.truncate( imageName.length() - 2 );
58 s_smileyEmoticonNameMap->insert( EmotIcons::smiley(i), imageName );
62 if ( !s_smileyEmoticonHTMLCache )
63 smileyCacheDeleter.setObject( s_smileyEmoticonHTMLCache,
64 new TQMap<TQString, TQString>() );
79 mMaxAddressLen = length;
84 return mMaxAddressLen;
95 TQString(
"<>()[]").find(
mText[
mPos]) == -1)
100 const TQString allowedSpecialChars = TQString(
"#/&-_");
102 allowedSpecialChars.find(
mText[
mPos-1]) == -1 )
122bool LinkLocator::atUrl()
const
126 const TQString allowedSpecialChars = TQString(
".!#$%&'*+-/=?^_`{|}~");
131 ( allowedSpecialChars.find(
mText[
mPos-1] ) != -1 ) ) )
135 return (ch==
'h' && (
mText.mid(
mPos, 7) ==
"http://" ||
137 (ch==
'v' &&
mText.mid(
mPos, 6) ==
"vnc://") ||
138 (ch==
'f' && (
mText.mid(
mPos, 7) ==
"fish://" ||
141 (ch==
's' && (
mText.mid(
mPos, 7) ==
"sftp://" ||
143 (ch==
'm' &&
mText.mid(
mPos, 7) ==
"mailto:") ||
144 (ch==
'w' &&
mText.mid(
mPos, 4) ==
"www.") ||
145 (ch==
'f' &&
mText.mid(
mPos, 4) ==
"ftp.") ||
146 (ch==
'n' &&
mText.mid(
mPos, 5) ==
"news:");
150bool LinkLocator::isEmptyUrl(
const TQString& url)
152 return url.isEmpty() ||
175 const TQString allowedSpecialChars = TQString(
".!#$%&'*+-/=?^_`{|}~");
178 int start =
mPos - 1;
179 while ( start >= 0 &&
mText[start].unicode() < 128 &&
180 (
mText[start].isLetterOrNumber() ||
181 mText[start] ==
'@' ||
182 allowedSpecialChars.find(
mText[start] ) != -1 ) ) {
183 if (
mText[start] ==
'@' )
189 while ( ( start <
mPos ) && !
mText[start].isLetterOrNumber() )
195 int dotPos = INT_MAX;
197 while ( end < (
int)
mText.length() &&
198 (
mText[end].isLetterOrNumber() ||
201 mText[end] ==
'-' ) ) {
202 if (
mText[end] ==
'@' )
204 if (
mText[end] ==
'.' )
205 dotPos = TQMIN( dotPos, end );
209 while ( ( end >
mPos ) && !
mText[end - 1].isLetterOrNumber() )
218 address =
mText.mid( start, end - start );
233 TQString result((TQChar*)0, (
int)locator.
mText.length() * 2);
236 bool startOfLine =
true;
239 for (locator.
mPos = 0, x = 0; locator.
mPos < (
int)locator.
mText.length(); locator.
mPos++, x++)
242 if ( flags & PreserveSpaces )
251 while (locator.
mText[locator.
mPos] ==
' ')
255 if (locator.
mText[locator.
mPos] ==
' ') {
295 const int start = locator.
mPos;
296 if ( !(flags & IgnoreUrls) ) {
301 if(str.left(4) ==
"www.")
302 hyperlink =
"http://" + str;
303 else if(str.left(4) ==
"ftp.")
304 hyperlink =
"ftp://" + str;
308 str = str.replace(
'&',
"&");
309 result +=
"<a href=\"" + hyperlink +
"\">" + str +
"</a>";
310 x += locator.
mPos - start;
317 int len = str.find(
'@');
318 TQString localPart = str.left(len);
322 result.truncate(result.length() - len - (localPart.contains(
'&')*4));
325 result +=
"<a href=\"mailto:" + str +
"\">" + str +
"</a>";
326 x += str.length() - 1;
330 if ( flags & ReplaceSmileys ) {
331 str = locator.getEmoticon();
332 if ( ! str.isEmpty() ) {
334 x += locator.
mPos - start;
338 if ( flags & HighlightText ) {
339 str = locator.highlightedText();
340 if ( !str.isEmpty() ) {
342 x += locator.
mPos - start;
355 if ( iconPath.isEmpty() )
358 TQFile pngFile( iconPath );
359 if ( !pngFile.open( IO_ReadOnly | IO_Raw ) )
362 TQByteArray ba = pngFile.readAll();
364 return TQString::fromLatin1(
"data:image/png;base64,%1")
365 .arg( KCodecs::base64Encode( ba ).data() );
369TQString LinkLocator::getEmoticon()
377 if ( ch !=
':' && ch !=
';' && ch !=
'(' && ch !=
'8' )
382 const int MinSmileyLen = 2;
383 const int MaxSmileyLen = 4;
385 while ( ( smileyLen <= MaxSmileyLen ) &&
386 (
mPos+smileyLen < (
int)
mText.length() ) &&
389 if ( smileyLen < MinSmileyLen || smileyLen > MaxSmileyLen )
392 const TQString smiley =
mText.mid(
mPos, smileyLen );
393 if ( !s_smileyEmoticonNameMap->contains( smiley ) )
397 if ( s_smileyEmoticonHTMLCache->contains( smiley ) ) {
398 htmlRep = (*s_smileyEmoticonHTMLCache)[smiley];
401 const TQString imageName = (*s_smileyEmoticonNameMap)[smiley];
402 const TQString iconPath = locate(
"emoticons",
404 TQString::fromLatin1(
"/" ) +
405 imageName + TQString::fromLatin1(
".png") );
407 if ( dataUrl.isEmpty() ) {
408 htmlRep = TQString();
413 htmlRep = TQString(
"<img class=\"pimsmileyimg\" src=\"%1\" "
414 "alt=\"%2\" title=\"%3\" width=\"16\" height=\"16\"/>")
416 TQStyleSheet::escape( smiley ),
417 TQStyleSheet::escape( smiley ) );
419 s_smileyEmoticonHTMLCache->insert( smiley, htmlRep );
422 if ( !htmlRep.isEmpty() )
423 mPos += smileyLen - 1;
428TQString LinkLocator::highlightedText()
435 if ( ch !=
'/' && ch !=
'*' && ch !=
'_' )
438 TQRegExp re = TQRegExp( TQString(
"\\%1([0-9A-Za-z]+)\\%2").arg( ch ).arg( ch ) );
440 uint length = re.matchedLength();
445 switch ( ch.latin1() ) {
447 return "<b>" + re.cap( 1 ) +
"</b>";
449 return "<u>" + re.cap( 1 ) +
"</u>";
451 return "<i>" + re.cap( 1 ) +
"</i>";
int maxAddressLen() const
TQString getEmailAddress()
Attempts to grab an email address.
void setMaxUrlLen(int length)
Sets the maximum length of URLs that will be matched by getUrl().
static TQString pngToDataUrl(const TQString &iconPath)
Embed the given PNG image into a data URL.
void setMaxAddressLen(int length)
Sets the maximum length of email addresses that will be matched by getEmailAddress().
static TQString convertToHtml(const TQString &plainText, int flags=0, int maxUrlLen=4096, int maxAddressLen=255)
Converts plaintext into html.
int mPos
The current scan position.
LinkLocator(const TQString &text, int pos=0)
Constructs a LinkLocator that will search a plaintext string from a given starting point.
TQString mText
The plaintext string being scanned for URLs and email addresses.
TQString getUrl()
Attempts to grab a URL starting at the current scan position.