Improve URL regexp a bit, don't fail anymore in certain situations
authorManuel Nickschas <sputnick@quassel-irc.org>
Wed, 17 Sep 2008 22:11:52 +0000 (00:11 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 17 Sep 2008 22:12:53 +0000 (00:12 +0200)
src/qtui/chatitem.cpp

index 50d74f5..a087d6c 100644 (file)
@@ -304,11 +304,12 @@ void ContentsChatItem::updateLayout() {
 //       (RegExps are not constant while matching, and they are static here for efficiency)
 QList<ContentsChatItem::Clickable> ContentsChatItem::findClickables() {
   // For matching URLs
-  static QString urlEnd("(?:>|[,.;:]?\\s|\\b)");
+  static QString urlEnd("(?:>|[,.;:\"]*\\s|\\b|$)");
   static QString urlChars("(?:[\\w\\-~@/?&=+$()!%#]|[,.;:]\\w)");
 
   static QRegExp regExp[] = {
     // URL
+    // QRegExp(QString("((?:https?://|s?ftp://|irc://|mailto:|www\\.)%1+|%1+\\.[a-z]{2,4}(?:?=/%1+|\\b))%2").arg(urlChars, urlEnd)),
     QRegExp(QString("((?:(?:https?://|s?ftp://|irc://|mailto:)|www)%1+)%2").arg(urlChars, urlEnd)),
 
     // Channel name
@@ -334,18 +335,21 @@ QList<ContentsChatItem::Clickable> ContentsChatItem::findClickables() {
     type = -1;
     minidx = str.length();
     for(int i = 0; i < regExpCount; i++) {
-      if(matches[i] < 0 || idx < matchEnd[i] || matchEnd[i] >= str.length()) continue;
-      matches[i] = str.indexOf(regExp[i], qMax(matchEnd[i], idx));
-      if(matches[i] >= 0) {
-        matchEnd[i] = matches[i] + regExp[i].cap(1).length();
-        if(matches[i] < minidx) {
-          minidx = matches[i];
-          type = i;
-        }
+      if(matches[i] < 0 || matchEnd[i] > str.length()) continue;
+      if(idx >= matchEnd[i]) {
+        matches[i] = str.indexOf(regExp[i], qMax(matchEnd[i], idx));
+        if(matches[i] >= 0) matchEnd[i] = matches[i] + regExp[i].cap(1).length();
+      }
+      if(matches[i] >= 0 && matches[i] < minidx) {
+        minidx = matches[i];
+        type = i;
       }
     }
     if(type >= 0) {
       idx = matchEnd[type];
+      if(type == Clickable::Url && str.at(idx-1) == ')') {  // special case: closing paren only matches if we had an open one
+        if(!str.mid(matches[type], matchEnd[type]-matches[type]).contains('(')) matchEnd[type]--;
+      }
       result.append(Clickable((Clickable::Type)type, matches[type], matchEnd[type] - matches[type]));
     }
   } while(type >= 0);
@@ -432,7 +436,7 @@ void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
         onClickable = true;
       else if(click.type == Clickable::Channel) {
         // TODO: don't make clickable if it's our own name
-        //onClickable = true; FIXME disabled for now
+        //onClickable = true; //FIXME disabled for now
       }
       if(onClickable) {
         setCursor(Qt::PointingHandCursor);