summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDon Sanders <don.sanders@nokia.com>2009-04-17 11:58:53 +1000
committerDon Sanders <don.sanders@nokia.com>2009-04-17 11:58:53 +1000
commit6e7d4a15c5a29414ed33d1ab709574949335172b (patch)
tree32eee591a9311a133c1d55ea871cd3d8a4f134da
parent45f1260086852b7f495cbe6f54f6fde513b6db62 (diff)
parentc9766cf1692888ab1a202587fcb592631fb2c94a (diff)
Merge branch 'qmf-1.0' of git@scm.dev.nokia.troll.no:addons/messagingframework into qmf-1.02009W16
-rw-r--r--src/plugins/viewers/generic/browser.cpp196
-rw-r--r--src/plugins/viewers/generic/browser.h2
2 files changed, 103 insertions, 95 deletions
diff --git a/src/plugins/viewers/generic/browser.cpp b/src/plugins/viewers/generic/browser.cpp
index 9e4d9f9e..e81f1383 100644
--- a/src/plugins/viewers/generic/browser.cpp
+++ b/src/plugins/viewers/generic/browser.cpp
@@ -915,8 +915,12 @@ QString Browser::encodeUrlAndMail(const QString& txt)
// We should be optimistic in our URL matching - the link resolution can
// always fail, but if we don't match it, then we can't make it into a link
- QRegExp urlPattern("((?:http|https|ftp)://)?" // optional scheme
- "((?:[^:]+:)?[^@]+@)?" // optional credentials
+ QRegExp urlPattern("("
+ "(?:http|https|ftp)://"
+ "|"
+ "mailto:"
+ ")?" // optional scheme
+ "((?:[^: \\t]+:)?[^ \\t@]+@)?" // optional credentials
"(" // either:
"localhost" // 'localhost'
"|" // or:
@@ -933,128 +937,132 @@ QString Browser::encodeUrlAndMail(const QString& txt)
")?" // end of optional group
")" // end of alternation
"(:\\d+)?" // optional port number
- "(" // optional trailer
+ "(" // optional location
"/" // beginning with a slash
"[A-Za-z\\d\\.\\!\\#\\$\\%\\'" // containing any sequence of legal chars
"\\*\\+\\-\\/\\=\\?\\^\\_\\`"
"\\{\\|\\}\\~\\&\\(\\)]*"
")?");
+ // Find and encode file:// links
QRegExp filePattern("(file://\\S+)");
// Find and encode email addresses
QRegExp addressPattern(QMailAddress::emailAddressPattern());
- int lastUrlPos = 0;
- while (lastUrlPos != -1) {
- QString url;
- QString scheme;
- QString trailing;
- QString nonurl;
+ int urlPos = urlPattern.indexIn(txt);
+ int addressPos = addressPattern.indexIn(txt);
+ int filePos = filePattern.indexIn(txt);
+
+ int lastPos = 0;
+ while ((urlPos != -1) || (addressPos != -1) || (filePos != -1)) {
+ int *matchPos = 0;
+ QRegExp *matchPattern = 0;
+
+ // Which pattern has the first match?
+ if ((urlPos != -1) &&
+ ((addressPos == -1) || (addressPos >= urlPos)) &&
+ ((filePos == -1) || (filePos >= urlPos))) {
+ matchPos = &urlPos;
+ matchPattern = &urlPattern;
+ } else if ((addressPos != -1) &&
+ ((urlPos == -1) || (urlPos >= addressPos)) &&
+ ((filePos == -1) || (filePos >= addressPos))) {
+ matchPos = &addressPos;
+ matchPattern = &addressPattern;
+ } else if ((filePos != -1) &&
+ ((urlPos == -1) || (urlPos >= filePos)) &&
+ ((addressPos == -1) || (addressPos >= filePos))) {
+ matchPos = &filePos;
+ matchPattern = &filePattern;
+ }
- int nextUrlPos = -1;
- int urlPos = urlPattern.indexIn(txt, lastUrlPos);
- if (urlPos != -1) {
- // Is this a valid URL?
- url = urlPattern.cap(0);
- scheme = urlPattern.cap(1);
+ QString replacement;
- nextUrlPos = urlPos + url.length();
+ if (matchPattern == &urlPattern) {
+ // Is this a valid URL?
+ QString scheme = urlPattern.cap(1);
+ QString credentials = urlPattern.cap(2);
+ QString host(urlPattern.cap(3));
// Ensure that the host is not purely a number
- QString host(urlPattern.cap(3));
- if (scheme.isEmpty() && (host.indexOf(QRegExp("[^\\d\\.]")) == -1)) {
+ // Also ignore credentials with no scheme
+ if (scheme.isEmpty() &&
+ ((host.indexOf(QRegExp("[^\\d\\.]")) == -1) || (!credentials.isEmpty()))) {
// Ignore this match
- nonurl = txt.mid(lastUrlPos, (nextUrlPos - lastUrlPos));
- url = QString();
+ urlPos = urlPattern.indexIn(txt, urlPos + 1);
+ continue;
} else {
- QString location(urlPattern.cap(5));
- if (!location.isEmpty()) {
- QChar lastChar(location.at(location.length() - 1));
- if (lastChar == ')') {
+ char parenTypes[] = { '(', ')', '[', ']', '{', '}', '<', '>', '\0' };
+
+ QString leading;
+ QString trailing;
+ QString url = urlPattern.cap(0);
+
+ QChar firstChar(url.at(0));
+ QChar lastChar(url.at(url.length() - 1));
+
+ for (int i = 0; parenTypes[i] != '\0'; i += 2) {
+ if ((firstChar == parenTypes[i]) || (lastChar == parenTypes[i+1])) {
// Check for unbalanced parentheses
- int left = location.count('(');
- int right = location.count(')');
+ int left = url.count(parenTypes[i]);
+ int right = url.count(parenTypes[i+1]);
- if (right > left) {
- // The last parentheses are probably not part of the URL
+ if ((right > left) && (lastChar == parenTypes[i+1])) {
+ // The last parenthesis is probably not part of the URL
url = url.left(url.length() - 1);
- trailing = lastChar;
+ trailing.append(lastChar);
+ lastChar = url.at(url.length() - 1);
+ } else if ((right < left) && (firstChar == parenTypes[i])) {
+ // The first parenthesis is probably not part of the URL
+ url = url.mid(1);
+ leading.append(firstChar);
+ firstChar = url.at(0);
}
- } else if ((lastChar == '.') || (lastChar == ',') || (lastChar == ';')) {
- // The last character is probably part of the surrounding text
- url = url.left(url.length() - 1);
- trailing = lastChar;
}
}
- nonurl = txt.mid(lastUrlPos, (urlPos - lastUrlPos));
+ if ((lastChar == '.') || (lastChar == ',') || (lastChar == ';')) {
+ // The last character is probably part of the surrounding text
+ url = url.left(url.length() - 1);
+ trailing = lastChar;
+ }
+
+ replacement = refUrl(url, scheme, leading, trailing);
}
+ } else if (matchPattern == &addressPattern) {
+ QString address = addressPattern.cap(0);
- } else {
- nonurl = txt.mid(lastUrlPos);
+ replacement = refMailTo(QMailAddress(address));
+ } else if (matchPattern == &filePattern) {
+ QString file = filePattern.cap(0);
+
+ replacement = refUrl(file, "file://", QString(), QString());
}
-
- if (!nonurl.isEmpty()) {
- // See if there are any file:// links in the non-URL part
- int lastFilePos = 0;
- while (lastFilePos != -1) {
- QString file;
- QString nonfile;
-
- int nextFilePos = -1;
- int filePos = filePattern.indexIn(nonurl, lastFilePos);
- if (filePos != -1) {
- nonfile = nonurl.mid(lastFilePos, (filePos - lastFilePos));
- file = filePattern.cap(0);
- nextFilePos = filePos + file.length();
- } else {
- nonfile = nonurl.mid(lastFilePos);
- }
-
- if (!nonfile.isEmpty()) {
- // See if there are any addresses in the non-URL part
- int lastAddressPos = 0;
- while (lastAddressPos != -1) {
- QString address;
- QString nonaddress;
-
- int nextAddressPos = -1;
- int addressPos = addressPattern.indexIn(nonfile, lastAddressPos);
- if (addressPos != -1) {
- nonaddress = nonfile.mid(lastAddressPos, (addressPos - lastAddressPos));
- address = addressPattern.cap(0);
- nextAddressPos = addressPos + address.length();
- } else {
- nonaddress = nonfile.mid(lastAddressPos);
- }
-
- if (!nonaddress.isEmpty()) {
- // Write this plain text out in escaped form
- result.append(Qt::escape(nonaddress));
- }
- if (!address.isEmpty()) {
- // Write out the address link
- result.append(refMailTo(QMailAddress(address)));
- }
- lastAddressPos = nextAddressPos;
- }
- }
- if (!file.isEmpty()) {
- // Write out the file link
- result.append(refUrl(file, "file://", QString()));
- }
+ // Write the unmatched text out in escaped form
+ result.append(Qt::escape(txt.mid(lastPos, (*matchPos - lastPos))));
- lastFilePos = nextFilePos;
- }
+ result.append(replacement);
+
+ // Find the following pattern match for this pattern
+ lastPos = *matchPos + matchPattern->cap(0).length();
+ *matchPos = matchPattern->indexIn(txt, lastPos);
+
+ // Bypass any other matches contained within the matched text
+ if ((urlPos != -1) && (urlPos < lastPos)) {
+ urlPos = urlPattern.indexIn(txt, lastPos);
+ }
+ if ((addressPos != -1) && (addressPos < lastPos)) {
+ addressPos = addressPattern.indexIn(txt, lastPos);
}
- if (!url.isEmpty()) {
- // Write out the URL link
- result.append(refUrl(url, scheme, trailing));
+ if ((filePos != -1) && (filePos < lastPos)) {
+ filePos = filePattern.indexIn(txt, lastPos);
}
+ }
- lastUrlPos = nextUrlPos;
+ if (lastPos < txt.length()) {
+ result.append(Qt::escape(txt.mid(lastPos)));
}
return result.join("");
@@ -1086,13 +1094,13 @@ QString Browser::refNumber(const QString& number)
return "<a href=\"dial;" + Qt::escape(number) + "\">" + number + "</a>";
}
-QString Browser::refUrl(const QString& url, const QString& scheme, const QString& trailing)
+QString Browser::refUrl(const QString& url, const QString& scheme, const QString& leading, const QString& trailing)
{
// Assume HTTP if there is no scheme
QString escaped(Qt::escape(url));
QString target(scheme.isEmpty() ? "http://" + escaped : escaped);
- return "<a href=\"" + target + "\">" + escaped + "</a>" + Qt::escape(trailing);
+ return Qt::escape(leading) + "<a href=\"" + target + "\">" + escaped + "</a>" + Qt::escape(trailing);
}
void Browser::keyPressEvent(QKeyEvent* event)
diff --git a/src/plugins/viewers/generic/browser.h b/src/plugins/viewers/generic/browser.h
index 240dd0ae..cce0fd50 100644
--- a/src/plugins/viewers/generic/browser.h
+++ b/src/plugins/viewers/generic/browser.h
@@ -76,7 +76,7 @@ private:
static QString listRefMailTo(const QList<QMailAddress>& list);
static QString refMailTo(const QMailAddress& address);
static QString refNumber(const QString& number);
- static QString refUrl(const QString& url, const QString& scheme, const QString& trailing);
+ static QString refUrl(const QString& url, const QString& scheme, const QString& leading, const QString& trailing);
QMap<QUrl, QVariant> resourceMap;
QString (Browser::*replySplitter)(const QString&) const;