Changeset 4535

Show
Ignore:
Timestamp:
07/21/06 05:26:48 (2 years ago)
Author:
erijo
Message:

Redo some of the logic for turning links into clickable links. Some small
changes to the regular expressions, most notable the abillity to recognize
urls starting with www (except www.com) as urls, but mostly just changes in
the logic.

Fixes second part of #733.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/qt-gui/src/mlview3.cpp

    r4526 r4535  
    8888  gMainWindow->emoticons->ParseMessage(text); 
    8989 
    90     // We must hightlight URLs at this step, before we convert 
    91     // linebreaks to richtext tags and such.  Also, check to make sure 
    92     // that the text is not prepared to be highlighted already (by AIM). 
    93     QRegExp reAHREF("<a href", false); 
     90  // We must hightlight URLs at this step, before we convert 
     91  // linebreaks to richtext tags and such.  Also, check to make sure 
     92  // that the text is not prepared to be highlighted already (by AIM). 
     93  QRegExp reAHREF("<a href", false); 
     94  if (highlightURLs && text.find(reAHREF) == -1) 
     95  { 
     96    QRegExp reURL( 
     97      "(?:(https?|ftp)://(.+(:.+)?@)?|www\\d?\\.)"  // protocoll://[user[:password]@] or www[digit]. 
     98      "[a-z0-9.-]+\\.([a-z]+|[0-9]+)"               // hostname.tld or ip address 
     99      "(:[0-9]+)?"                                  // optional port 
     100      "(/([-a-z0-9%{}|\\\\^~`;/?:@=&$_.+!*'(),#]|\\[|\\])*)?"); 
     101    reURL.setMinimal(false); 
     102    reURL.setCaseSensitive(false); 
     103 
     104    QRegExp reMail( 
     105      "(mailto:)?" 
     106      "[a-z9-0._%+-]+" 
     107      "@" 
     108      "[a-z0-9.-]+\\.(?:[a-z]+|[0-9]+)"); 
     109    reMail.setMinimal(false); 
     110    reMail.setCaseSensitive(false); 
     111 
    94112    int pos = 0; 
    95     if (highlightURLs && (pos = text.find(reAHREF, pos)) == -1) 
     113    while ((unsigned int)pos < text.length()) 
    96114    { 
    97        QRegExp reURL("(\\b|^)((https?|ftp)://([-a-z0-9]+(:[-a-z0-9]+)?@)?[-a-z0-9.]+[-a-z0-9](:[0-9]+)?(/([-a-z0-9%{}|\\\\^~`;/?:@=&$_.+!*'(),#]|\\[|\\])*)?)"); 
    98        reURL.setMinimal(false); 
    99        reURL.setCaseSensitive(false); 
    100        pos = 0; 
    101        while ( (pos = text.find(reURL, pos)) != -1 ) { 
    102           QString url = reURL.cap(2); 
    103           QString link = QString::fromLatin1("<a href=\"") + url + QString::fromLatin1("\">") + url + QString::fromLatin1("</a>"); 
    104           text.replace(pos, url.length(), link); 
    105           pos += reURL.matchedLength() - url.length() + link.length(); 
    106        } 
    107  
    108        QRegExp reMail("(mailto:)?([\\d\\w\\.\\-_]+@[\\d\\w\\.\\-_]+)(\\s+|$)"); 
    109        reMail.setMinimal(true); 
    110        pos = 0; 
    111        while ( (pos = text.find(reMail, pos)) != -1 ) { 
    112           QString mail = reMail.cap(2); 
    113           QString link = QString::fromLatin1("<a href=\"mailto:") + mail + QString::fromLatin1("\">") + mail + QString::fromLatin1("</a>"); 
    114           text.replace(pos, mail.length(), link); 
    115           pos += reMail.matchedLength() - mail.length() + link.length(); 
    116        } 
    117  
     115      // We try to match both url and mail at the same time, and then 
     116      // uses the one that matched first. 
     117      const int urlPos = text.find(reURL, pos); 
     118      const int mailPos = text.find(reMail, pos); 
     119 
     120      if (urlPos == -1 && mailPos == -1) 
     121        break; 
     122 
     123      if ((urlPos != -1 && urlPos <= mailPos) || mailPos == -1) 
     124      { 
     125        const QString url = reURL.cap(); 
     126        const QString fullurl = (reURL.cap(1).isEmpty() ? QString("http://%1").arg(url) : url); 
     127        const QString link = QString("<a href=\"%1\">%2</a>").arg(fullurl).arg(url); 
     128        text.replace(urlPos, reURL.matchedLength(), link); 
     129        pos = urlPos + link.length(); 
     130      } 
     131      else 
     132      { 
     133        const QString mail = reMail.cap(); 
     134        const QString fullmail = (reMail.cap(1).isEmpty() ? QString("mailto:%1").arg(mail) : mail); 
     135        const QString link = QString("<a href=\"%1\">%2</a>").arg(fullmail).arg(mail); 
     136        text.replace(mailPos, reMail.matchedLength(), link); 
     137        pos = mailPos + link.length(); 
     138      } 
    118139    } 
    119  
    120     // convert linebreaks to <br> 
    121     text.replace(QRegExp("\n"), "<br>\n"); 
    122     // We keep the first space character as-is (to allow line wrapping) 
    123     // and convert the next characters to &nbsp;s (to preserve multiple 
    124     // spaces). 
    125     QRegExp longSpaces(" ([ ]+)"); 
    126     pos = 0; 
    127     QString cap; 
    128     while ((pos = longSpaces.search(text)) > -1) 
    129     { 
    130        cap = longSpaces.cap(1); 
    131        cap.replace(QRegExp(" "), "&nbsp;"); 
    132        text.replace(pos+1, longSpaces.matchedLength()-1, cap); 
    133     } 
    134     text.replace(QRegExp("\t"), " &nbsp;&nbsp;&nbsp;"); 
     140  } 
     141 
     142  // convert linebreaks to <br> 
     143  text.replace(QRegExp("\n"), "<br>\n"); 
     144  // We keep the first space character as-is (to allow line wrapping) 
     145  // and convert the next characters to &nbsp;s (to preserve multiple 
     146  // spaces). 
     147  QRegExp longSpaces(" ([ ]+)"); 
     148  QString cap; 
     149  int pos = 0; 
     150  while ((pos = longSpaces.search(text)) > -1) 
     151  { 
     152    cap = longSpaces.cap(1); 
     153    cap.replace(QRegExp(" "), "&nbsp;"); 
     154    text.replace(pos+1, longSpaces.matchedLength()-1, cap); 
     155  } 
     156  text.replace(QRegExp("\t"), " &nbsp;&nbsp;&nbsp;"); 
    135157 
    136158  return text;