23 #include "linklocator.h"
24 #include "pimemoticons.h"
25 #include <tdeversion.h>
26 #include <tdeglobal.h>
27 #include <kstandarddirs.h>
28 #include <kstaticdeleter.h>
32 #include <tqstylesheet.h>
38 TQMap<TQString, TQString> *LinkLocator::s_smileyEmoticonNameMap = 0;
39 TQMap<TQString, TQString> *LinkLocator::s_smileyEmoticonHTMLCache = 0;
41 static KStaticDeleter< TQMap<TQString, TQString> > smileyMapDeleter;
42 static KStaticDeleter< TQMap<TQString, TQString> > smileyCacheDeleter;
45 : mText(text), mPos(pos), mMaxUrlLen(4096), mMaxAddressLen(255)
53 if ( !s_smileyEmoticonNameMap ) {
54 smileyMapDeleter.setObject( s_smileyEmoticonNameMap,
55 new TQMap<TQString, TQString>() );
56 for (
int i = 0; i < EmotIcons::EnumSindex::COUNT; ++i ) {
57 TQString imageName( EmotIcons::EnumSindex::enumToString[i] );
58 imageName.truncate( imageName.length() - 2 );
59 s_smileyEmoticonNameMap->insert( EmotIcons::smiley(i), imageName );
63 if ( !s_smileyEmoticonHTMLCache )
64 smileyCacheDeleter.setObject( s_smileyEmoticonHTMLCache,
65 new TQMap<TQString, TQString>() );
80 mMaxAddressLen = length;
85 return mMaxAddressLen;
96 TQString(
"<>()[]").find(
mText[
mPos]) == -1)
101 const TQString allowedSpecialChars = TQString(
"#/&-_");
103 allowedSpecialChars.find(
mText[
mPos-1]) == -1 )
123 bool LinkLocator::atUrl()
const
127 const TQString allowedSpecialChars = TQString(
".!#$%&'*+-/=?^_`{|}~");
132 ( allowedSpecialChars.find(
mText[
mPos-1] ) != -1 ) ) )
136 return (ch==
'h' && (
mText.mid(
mPos, 7) ==
"http://" ||
138 (ch==
'v' &&
mText.mid(
mPos, 6) ==
"vnc://") ||
139 (ch==
'f' && (
mText.mid(
mPos, 7) ==
"fish://" ||
142 (ch==
's' && (
mText.mid(
mPos, 7) ==
"sftp://" ||
144 (ch==
'm' &&
mText.mid(
mPos, 7) ==
"mailto:") ||
145 (ch==
'w' &&
mText.mid(
mPos, 4) ==
"www.") ||
146 (ch==
'f' &&
mText.mid(
mPos, 4) ==
"ftp.") ||
147 (ch==
'n' &&
mText.mid(
mPos, 5) ==
"news:");
151 bool LinkLocator::isEmptyUrl(
const TQString& url)
153 return url.isEmpty() ||
176 const TQString allowedSpecialChars = TQString(
".!#$%&'*+-/=?^_`{|}~");
179 int start =
mPos - 1;
180 while ( start >= 0 &&
mText[start].unicode() < 128 &&
181 (
mText[start].isLetterOrNumber() ||
182 mText[start] ==
'@' ||
183 allowedSpecialChars.find(
mText[start] ) != -1 ) ) {
184 if (
mText[start] ==
'@' )
190 while ( ( start <
mPos ) && !
mText[start].isLetterOrNumber() )
196 int dotPos = INT_MAX;
198 while ( end < (
int)
mText.length() &&
199 (
mText[end].isLetterOrNumber() ||
202 mText[end] ==
'-' ) ) {
203 if (
mText[end] ==
'@' )
205 if (
mText[end] ==
'.' )
206 dotPos = TQMIN( dotPos, end );
210 while ( ( end >
mPos ) && !
mText[end - 1].isLetterOrNumber() )
219 address =
mText.mid( start, end - start );
227 int maxUrlLen,
int maxAddressLen)
234 TQString result((TQChar*)0, (
int)locator.
mText.length() * 2);
237 bool startOfLine =
true;
240 for (locator.
mPos = 0, x = 0; locator.
mPos < (
int)locator.
mText.length(); locator.
mPos++, x++)
243 if ( flags & PreserveSpaces )
252 while (locator.
mText[locator.
mPos] ==
' ')
256 if (locator.
mText[locator.
mPos] ==
' ') {
296 const int start = locator.
mPos;
297 if ( !(flags & IgnoreUrls) ) {
302 if(str.left(4) ==
"www.")
303 hyperlink =
"http://" + str;
304 else if(str.left(4) ==
"ftp.")
305 hyperlink =
"ftp://" + str;
309 str = str.replace(
'&',
"&");
310 result +=
"<a href=\"" + hyperlink +
"\">" + str +
"</a>";
311 x += locator.
mPos - start;
318 int len = str.find(
'@');
319 TQString localPart = str.left(len);
323 result.truncate(result.length() - len - (localPart.contains(
'&')*4));
326 result +=
"<a href=\"mailto:" + str +
"\">" + str +
"</a>";
327 x += str.length() - 1;
331 if ( flags & ReplaceSmileys ) {
332 str = locator.getEmoticon();
333 if ( ! str.isEmpty() ) {
335 x += locator.
mPos - start;
339 if ( flags & HighlightText ) {
340 str = locator.highlightedText();
341 if ( !str.isEmpty() ) {
343 x += locator.
mPos - start;
356 if ( iconPath.isEmpty() )
359 TQFile pngFile( iconPath );
360 if ( !pngFile.open( IO_ReadOnly | IO_Raw ) )
363 TQByteArray ba = pngFile.readAll();
365 return TQString::fromLatin1(
"data:image/png;base64,%1")
366 .arg( KCodecs::base64Encode( ba ).data() );
370 TQString LinkLocator::getEmoticon()
378 if ( ch !=
':' && ch !=
';' && ch !=
'(' && ch !=
'8' )
383 const int MinSmileyLen = 2;
384 const int MaxSmileyLen = 4;
386 while ( ( smileyLen <= MaxSmileyLen ) &&
387 (
mPos+smileyLen < (
int)
mText.length() ) &&
390 if ( smileyLen < MinSmileyLen || smileyLen > MaxSmileyLen )
393 const TQString smiley =
mText.mid(
mPos, smileyLen );
394 if ( !s_smileyEmoticonNameMap->contains( smiley ) )
398 if ( s_smileyEmoticonHTMLCache->contains( smiley ) ) {
399 htmlRep = (*s_smileyEmoticonHTMLCache)[smiley];
402 const TQString imageName = (*s_smileyEmoticonNameMap)[smiley];
404 #if KDE_IS_VERSION( 3, 3, 91 )
405 const TQString iconPath = locate(
"emoticons",
407 TQString::fromLatin1(
"/" ) +
408 imageName + TQString::fromLatin1(
".png") );
410 const TQString iconPath = locate(
"data",
411 TQString::fromLatin1(
"kopete/pics/emoticons/" )+
413 TQString::fromLatin1(
"/" ) +
414 imageName + TQString::fromLatin1(
".png") );
418 if ( dataUrl.isEmpty() ) {
419 htmlRep = TQString();
424 htmlRep = TQString(
"<img class=\"pimsmileyimg\" src=\"%1\" "
425 "alt=\"%2\" title=\"%3\" width=\"16\" height=\"16\"/>")
427 TQStyleSheet::escape( smiley ),
428 TQStyleSheet::escape( smiley ) );
430 s_smileyEmoticonHTMLCache->insert( smiley, htmlRep );
433 if ( !htmlRep.isEmpty() )
434 mPos += smileyLen - 1;
439 TQString LinkLocator::highlightedText()
446 if ( ch !=
'/' && ch !=
'*' && ch !=
'_' )
449 TQRegExp re = TQRegExp( TQString(
"\\%1([0-9A-Za-z]+)\\%2").arg( ch ).arg( ch ) );
451 uint length = re.matchedLength();
456 switch ( ch.latin1() ) {
458 return "<b>" + re.cap( 1 ) +
"</b>";
460 return "<u>" + re.cap( 1 ) +
"</u>";
462 return "<i>" + re.cap( 1 ) +
"</i>";
LinkLocator assists in identifying sections of text that can usefully be converted in hyperlinks in h...
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.