23 #include "linklocator.h" 24 #include "pimemoticons.h" 25 #include <tdeglobal.h> 26 #include <kstandarddirs.h> 27 #include <kstaticdeleter.h> 31 #include <tqstylesheet.h> 37 TQMap<TQString, TQString> *LinkLocator::s_smileyEmoticonNameMap = 0;
38 TQMap<TQString, TQString> *LinkLocator::s_smileyEmoticonHTMLCache = 0;
40 static KStaticDeleter< TQMap<TQString, TQString> > smileyMapDeleter;
41 static 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(
"#/&-_");
101 while(mPos > start &&
mText[mPos-1].isPunct() &&
102 allowedSpecialChars.find(
mText[mPos-1]) == -1 )
107 url =
mText.mid(start, mPos - start);
108 if(isEmptyUrl(url) || mPos - start >
maxUrlLen())
122 bool 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:");
150 bool 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() );
369 TQString 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];
403 #if KDE_IS_VERSION( 3, 3, 91 ) 404 const TQString iconPath = locate(
"emoticons",
406 TQString::fromLatin1(
"/" ) +
407 imageName + TQString::fromLatin1(
".png") );
409 const TQString iconPath = locate(
"data",
410 TQString::fromLatin1(
"kopete/pics/emoticons/" )+
412 TQString::fromLatin1(
"/" ) +
413 imageName + TQString::fromLatin1(
".png") );
417 if ( dataUrl.isEmpty() ) {
418 htmlRep = TQString();
423 htmlRep = TQString(
"<img class=\"pimsmileyimg\" src=\"%1\" " 424 "alt=\"%2\" title=\"%3\" width=\"16\" height=\"16\"/>")
426 TQStyleSheet::escape( smiley ),
427 TQStyleSheet::escape( smiley ) );
429 s_smileyEmoticonHTMLCache->insert( smiley, htmlRep );
432 if ( !htmlRep.isEmpty() )
433 mPos += smileyLen - 1;
438 TQString LinkLocator::highlightedText()
445 if ( ch !=
'/' && ch !=
'*' && ch !=
'_' )
448 TQRegExp re = TQRegExp( TQString(
"\\%1([0-9A-Za-z]+)\\%2").arg( ch ).arg( ch ) );
450 uint length = re.matchedLength();
455 switch ( ch.latin1() ) {
457 return "<b>" + re.cap( 1 ) +
"</b>";
459 return "<u>" + re.cap( 1 ) +
"</u>";
461 return "<i>" + re.cap( 1 ) +
"</i>";
int maxAddressLen() const
static TQString pngToDataUrl(const TQString &iconPath)
Embed the given PNG image into a data URL.
void setMaxUrlLen(int length)
Sets the maximum length of URLs that will be matched by getUrl().
static TQString convertToHtml(const TQString &plainText, int flags=0, int maxUrlLen=4096, int maxAddressLen=255)
Converts plaintext into html.
TQString getUrl()
Attempts to grab a URL starting at the current scan position.
TQString mText
The plaintext string being scanned for URLs and email addresses.
int mPos
The current scan position.
void setMaxAddressLen(int length)
Sets the maximum length of email addresses that will be matched by getEmailAddress().
LinkLocator(const TQString &text, int pos=0)
Constructs a LinkLocator that will search a plaintext string from a given starting point...
TQString getEmailAddress()
Attempts to grab an email address.
LinkLocator assists in identifying sections of text that can usefully be converted in hyperlinks in h...