Sanitize handling of mirc color codes in order to ease parsing of the
authorManuel Nickschas <sputnick@quassel-irc.org>
Sat, 20 Oct 2007 01:29:10 +0000 (01:29 +0000)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sat, 20 Oct 2007 01:29:10 +0000 (01:29 +0000)
internal format.

src/common/message.cpp
src/qtopia/chatline.cpp
src/qtui/style.cpp

index 57ae388..46ae484 100644 (file)
@@ -69,12 +69,43 @@ QDateTime Message::timeStamp() const {
 QString Message::mircToInternal(QString mirc) {
   mirc.replace('%', "%%");      // escape % just to be sure
   mirc.replace('\x02', "%B");
 QString Message::mircToInternal(QString mirc) {
   mirc.replace('%', "%%");      // escape % just to be sure
   mirc.replace('\x02', "%B");
-  mirc.replace('\x03', "%C");
   mirc.replace('\x0f', "%O");
   mirc.replace('\x12', "%R");
   mirc.replace('\x16', "%R");
   mirc.replace('\x1d', "%S");
   mirc.replace('\x1f', "%U");
   mirc.replace('\x0f', "%O");
   mirc.replace('\x12', "%R");
   mirc.replace('\x16', "%R");
   mirc.replace('\x1d', "%S");
   mirc.replace('\x1f', "%U");
+
+  // Now we bring the color codes (\x03) in a sane format that can be parsed more easily later.
+  // %Dcfxx is foreground, %Dcbxx is background color, where xx is a 2 digit dec number denoting the color code.
+  // %Dc- turns color off.
+  // Note: We use the "mirc standard" as described in <http://www.mirc.co.uk/help/color.txt>.
+  //       This means that we don't accept something like \x03,5 (even though others, like WeeChat, do).
+  int pos = 0;
+  for(;;) {
+    pos = mirc.indexOf('\x03', pos);
+    if(pos < 0) break; // no more mirc color codes
+    QString ins, num;
+    int l = mirc.length();
+    int i = pos + 1;
+    // check for fg color
+    if(i < l && mirc[i].isDigit()) {
+      num = mirc[i++];
+      if(i < l && mirc[i].isDigit()) num.append(mirc[i++]);
+      else num.prepend('0');
+      ins = QString("%Dcf%1").arg(num);
+
+      if(i+1 < l && mirc[i] == ',' && mirc[i+1].isDigit()) {
+        i++;
+        num = mirc[i++];
+        if(i < l && mirc[i].isDigit()) num.append(mirc[i++]);
+        else num.prepend('0');
+        ins += QString("%Dcb%1").arg(num);
+      }
+    } else {
+      ins = "%Dc-";
+    }
+    mirc.replace(pos, i-pos, ins);
+  }
   return mirc;
 }
 
   return mirc;
 }
 
index d14be8e..eff324b 100644 (file)
@@ -68,6 +68,6 @@ QString ChatLine::htmlTimeStamp() const {
 
 
 QString ChatLine::formattedToHtml(const QString &f) {
 
 
 QString ChatLine::formattedToHtml(const QString &f) {
-
+  
   return f;
 }
   return f;
 }
index 67e53a8..0181187 100644 (file)
@@ -69,10 +69,8 @@ void Style::init() {
   // %C - 0x03 - mIRC colors
   for(uint i = 0; i < 16; i++) {
     QString idx = QString("%1").arg(i, (int)2, (int)10, (QChar)'0');
   // %C - 0x03 - mIRC colors
   for(uint i = 0; i < 16; i++) {
     QString idx = QString("%1").arg(i, (int)2, (int)10, (QChar)'0');
-    QString fg = QString("%C%1").arg(idx);
-    QString bg = QString("%C,%1").arg(idx);
-    QTextCharFormat fgf; fgf.setForeground(QBrush(colors[idx])); formats[fg] = fgf;
-    QTextCharFormat bgf; bgf.setBackground(QBrush(colors[idx])); formats[bg] = bgf;
+    QTextCharFormat fgf; fgf.setForeground(QBrush(colors[idx])); formats[QString("cf%1").arg(idx)] = fgf;
+    QTextCharFormat bgf; bgf.setBackground(QBrush(colors[idx])); formats[QString("cb%1").arg(idx)] = bgf;
   }
 
   // Internal formats - %D<char>
   }
 
   // Internal formats - %D<char>
@@ -170,47 +168,37 @@ Style::StyledString Style::formattedToStyled(QString s) {
   int i, j;
   for(i = 0, j = 0; i < s.length(); i++) {
     if(s[i] != '%') { p += s[i]; j++; continue; }
   int i, j;
   for(i = 0, j = 0; i < s.length(); i++) {
     if(s[i] != '%') { p += s[i]; j++; continue; }
-    i++;
-    if(s[i] == '%') { p += '%'; j++; continue; }
-    else if(s[i] == 'C') {
-      if(!s[i+1].isDigit() && s[i+1] != ',') {
+    if(s[++i] == '%') { p += '%'; j++; continue; }
+    else if(s[i] == 'D' && s[i+1] == 'c') {  // color code
+      if(s[i+2] == '-') {  // color off
+        if(toggles.contains("fg")) {
+          sf.formats[toggles["fg"]].length = j - sf.formats[toggles["fg"]].start;
+          toggles.remove("fg");
+        }
         if(toggles.contains("bg")) {
           sf.formats[toggles["bg"]].length = j - sf.formats[toggles["bg"]].start;
           toggles.remove("bg");
         }
         if(toggles.contains("bg")) {
           sf.formats[toggles["bg"]].length = j - sf.formats[toggles["bg"]].start;
           toggles.remove("bg");
         }
-      }
-      if(s[i+1].isDigit() || s[i+1] != ',') {
+        i += 2;
+      } else if(s[i+2] == 'f') { // foreground
         if(toggles.contains("fg")) {
           sf.formats[toggles["fg"]].length = j - sf.formats[toggles["fg"]].start;
           toggles.remove("fg");
         }
         if(toggles.contains("fg")) {
           sf.formats[toggles["fg"]].length = j - sf.formats[toggles["fg"]].start;
           toggles.remove("fg");
         }
-        if(s[i+1].isDigit()) {
-          QString n(s[++i]);
-          if(s[i+1].isDigit()) n += s[++i];
-          int num = n.toInt() & 0xf;
-          n = QString("%C%1").arg(num, (int)2, (int)10, (QChar)'0');
-          //qDebug() << n << formats[n].foreground();
-          QTextLayout::FormatRange range; 
-          range.format = formats[n]; range.start = j; range.length = -1; sf.formats.append(range);
-          toggles["fg"] = sf.formats.count() - 1;
-        }
-      }
-      if(s[i+1] == ',') {
+        QTextLayout::FormatRange range;
+        range.format = formats[s.mid(i+1, 4)]; range.start = j; range.length = -1; sf.formats.append(range);
+        toggles["fg"] = sf.formats.count() - 1;
+        i += 4;
+      } else {  // background
+        Q_ASSERT(s[i+2] == 'b');
         if(toggles.contains("bg")) {
           sf.formats[toggles["bg"]].length = j - sf.formats[toggles["bg"]].start;
           toggles.remove("bg");
         }
         if(toggles.contains("bg")) {
           sf.formats[toggles["bg"]].length = j - sf.formats[toggles["bg"]].start;
           toggles.remove("bg");
         }
-        i++;
-        if(s[i+1].isDigit()) {
-          QString n(s[++i]);
-          if(s[i+1].isDigit()) n += s[++i];
-          int num = n.toInt() & 0xf;
-          n = QString("%C,%1").arg(num, (int)2, (int)10, (QChar)'0');
-          QTextLayout::FormatRange range;
-          range.format = formats[n]; range.start = j; range.length = -1;
-          sf.formats.append(range);
-          toggles["bg"] = sf.formats.count() - 1;
-        }
+        QTextLayout::FormatRange range;
+        range.format = formats[s.mid(i+1, 4)]; range.start = j; range.length = -1; sf.formats.append(range);
+        toggles["bg"] = sf.formats.count() - 1;
+        i += 4;
       }
     } else if(s[i] == 'O') {
       foreach(QString key, toggles.keys()) {
       }
     } else if(s[i] == 'O') {
       foreach(QString key, toggles.keys()) {