00001
00023
#include "linklocator.h"
00024
00025
00026 LinkLocator::LinkLocator(
const QString& text,
int pos)
00027 : mText(text), mPos(pos), mMaxUrlLen(4096), mMaxAddressLen(255)
00028 {
00029
00030
00031
00032
00033
00034 }
00035
00036 void LinkLocator::setMaxUrlLen(
int length)
00037 {
00038 mMaxUrlLen = length;
00039 }
00040
00041 int LinkLocator::maxUrlLen()
const
00042
{
00043
return mMaxUrlLen;
00044 }
00045
00046 void LinkLocator::setMaxAddressLen(
int length)
00047 {
00048 mMaxAddressLen = length;
00049 }
00050
00051 int LinkLocator::maxAddressLen()
const
00052
{
00053
return mMaxAddressLen;
00054 }
00055
00056 QString LinkLocator::getUrl()
00057 {
00058
QString url;
00059
if(atUrl())
00060 {
00061
00062
int start =
mPos;
00063
while(mPos < (
int)
mText.length() &&
mText[mPos] >
' ' &&
mText[mPos] !=
'"' &&
00064
QString(
"<>()[]").find(mText[mPos]) == -1)
00065 {
00066 ++mPos;
00067 }
00068
00069
const QString allowedSpecialChars =
QString(
"#/&");
00070
while(mPos > start && mText[mPos-1].isPunct() &&
00071 allowedSpecialChars.find(mText[mPos-1]) == -1 )
00072 {
00073 --mPos;
00074 }
00075
00076 url = mText.mid(start, mPos - start);
00077
if(isEmptyUrl(url) || mPos - start >
maxUrlLen())
00078 {
00079 mPos = start;
00080 url =
"";
00081 }
00082
else
00083 {
00084 --mPos;
00085 }
00086 }
00087
return url;
00088 }
00089
00090
00091
bool LinkLocator::atUrl()
const
00092
{
00093
00094
00095
const QString allowedSpecialChars =
QString(
".!#$%&'*+-/=?^_`{|}~");
00096
00097
00098
00099
if( ( mPos > 0 ) && ( mText[mPos-1].isLetterOrNumber() ||
00100 ( allowedSpecialChars.find( mText[mPos-1] ) != -1 ) ) )
00101
return false;
00102
00103
QChar ch = mText[mPos];
00104
return (ch==
'h' && ( mText.mid(mPos, 7) ==
"http://" ||
00105 mText.mid(mPos, 8) ==
"https://") ) ||
00106 (ch==
'v' && mText.mid(mPos, 6) ==
"vnc://") ||
00107 (ch==
'f' && ( mText.mid(mPos, 6) ==
"ftp://" ||
00108 mText.mid(mPos, 7) ==
"ftps://") ) ||
00109 (ch==
's' && ( mText.mid(mPos, 7) ==
"sftp://" ||
00110 mText.mid(mPos, 6) ==
"smb://") ) ||
00111 (ch==
'm' && mText.mid(mPos, 7) ==
"mailto:") ||
00112 (ch==
'w' && mText.mid(mPos, 4) ==
"www.") ||
00113 (ch==
'f' && mText.mid(mPos, 4) ==
"ftp.");
00114
00115 }
00116
00117
bool LinkLocator::isEmptyUrl(
const QString& url)
00118 {
00119
return url.isEmpty() ||
00120 url ==
"http://" ||
00121 url ==
"https://" ||
00122 url ==
"ftp://" ||
00123 url ==
"ftps://" ||
00124 url ==
"sftp://" ||
00125 url ==
"smb://" ||
00126 url ==
"vnc://" ||
00127 url ==
"mailto" ||
00128 url ==
"www" ||
00129 url ==
"ftp";
00130 }
00131
00132 QString LinkLocator::getEmailAddress()
00133 {
00134
QString address;
00135
00136
if(
mText[
mPos] ==
'@')
00137 {
00138
00139
00140
const QString allowedSpecialChars =
QString(
".!#$%&'*+-/=?^_`{|}~");
00141
00142
00143
int start =
mPos - 1;
00144
while (start >= 0 &&
mText[start].unicode() < 128 &&
00145 (mText[start].isLetterOrNumber() ||
00146 mText[start] ==
'@' ||
00147 allowedSpecialChars.find(mText[start]) != -1))
00148 {
00149 --start;
00150 }
00151 ++start;
00152
00153
while (allowedSpecialChars.find(mText[start]) != -1)
00154 ++start;
00155
00156
00157
int end = mPos + 1;
00158
while (end < (
int)mText.length() &&
00159 (mText[end].isLetterOrNumber() ||
00160 mText[end] ==
'@' ||
00161 allowedSpecialChars.find(mText[end]) != -1))
00162 {
00163 ++end;
00164 }
00165
00166
while (allowedSpecialChars.find(mText[end - 1]) != -1)
00167 --end;
00168
00169 address = mText.mid(start, end - start);
00170
if(isEmptyAddress(address) || end - start >
maxAddressLen() || address.contains(
'@') != 1)
00171 address =
"";
00172
00173
if(!address.isEmpty())
00174 mPos = end - 1;
00175 }
00176
return address;
00177 }
00178
00179
bool LinkLocator::isEmptyAddress(
const QString& address)
00180 {
00181
return address.isEmpty() ||
00182 address[0] ==
'@' ||
00183 address[address.length() - 1] ==
'@';
00184 }
00185
00186 QString LinkLocator::convertToHtml(
const QString& plainText,
bool preserveBlanks,
00187
int maxUrlLen,
int maxAddressLen)
00188 {
00189
LinkLocator locator(plainText);
00190 locator.
setMaxUrlLen(maxUrlLen);
00191 locator.
setMaxAddressLen(maxAddressLen);
00192
00193
QString str;
00194
QString result((
QChar*)0, (
int)locator.
mText.length() * 2);
00195
QChar ch;
00196
int x;
00197
bool startOfLine =
true;
00198
00199
for (locator.
mPos = 0, x = 0; locator.
mPos < (
int)locator.
mText.length(); locator.
mPos++, x++)
00200 {
00201 ch = locator.
mText[locator.
mPos];
00202
if (preserveBlanks)
00203 {
00204
if (ch==
' ')
00205 {
00206
if (startOfLine) {
00207 result +=
" ";
00208 locator.
mPos++, x++;
00209 startOfLine =
false;
00210 }
00211
while (locator.
mText[locator.
mPos] ==
' ')
00212 {
00213 result +=
" ";
00214 locator.
mPos++, x++;
00215
if (locator.
mText[locator.
mPos] ==
' ') {
00216 result +=
" ";
00217 locator.
mPos++, x++;
00218 }
00219 }
00220 locator.
mPos--, x--;
00221
continue;
00222 }
00223
else if (ch==
'\t')
00224 {
00225
do
00226 {
00227 result +=
" ";
00228 x++;
00229 }
00230
while((x&7) != 0);
00231 x--;
00232 startOfLine =
false;
00233
continue;
00234 }
00235 }
00236
if (ch==
'\n')
00237 {
00238 result +=
"<br />";
00239 startOfLine =
true;
00240 x = -1;
00241
continue;
00242 }
00243
00244 startOfLine =
false;
00245
if (ch==
'&')
00246 result +=
"&";
00247
else if (ch==
'"')
00248 result +=
""";
00249
else if (ch==
'<')
00250 result +=
"<";
00251
else if (ch==
'>')
00252 result +=
">";
00253
else
00254 {
00255
int start = locator.
mPos;
00256 str = locator.
getUrl();
00257
if(!str.isEmpty())
00258 {
00259
QString hyperlink;
00260
if(str.left(4) ==
"www.")
00261 hyperlink =
"http://" + str;
00262
else if(str.left(4) ==
"ftp.")
00263 hyperlink =
"ftp://" + str;
00264
else
00265 hyperlink = str;
00266
00267 str = str.replace(
'&',
"&");
00268 result +=
"<a href=\"" + hyperlink +
"\">" + str +
"</a>";
00269 x += locator.
mPos - start;
00270 }
00271
else
00272 {
00273 str = locator.
getEmailAddress();
00274
if(!str.isEmpty())
00275 {
00276
00277
int len = str.find(
'@');
00278
QString localPart = str.left(len);
00279
00280
00281
00282 result.truncate(result.length() - len - (localPart.contains(
'&')*4));
00283 x -= len;
00284
00285 result +=
"<a href=\"mailto:" + str +
"\">" + str +
"</a>";
00286 x += str.length() - 1;
00287 }
00288
else
00289 {
00290 result += ch;
00291 }
00292 }
00293 }
00294 }
00295
00296
return result;
00297 }
00298
00299