Introduce extra Palette roles for UiStyle
[quassel.git] / src / uisupport / qssparser.cpp
index f46147b..091ac4b 100644 (file)
@@ -49,6 +49,22 @@ QssParser::QssParser()
   _paletteColorRoles["tooltip-text"] = QPalette::ToolTipText;
   _paletteColorRoles["window"] = QPalette::Window;
   _paletteColorRoles["window-text"] = QPalette::WindowText;
+
+  _uiStylePalette = QVector<QBrush>(UiStyle::NumRoles, QBrush());
+
+  _uiStyleColorRoles["marker-line"] = UiStyle::MarkerLine;
+  _uiStyleColorRoles["active-nick"] = UiStyle::ActiveNick;
+  _uiStyleColorRoles["inactive-nick"] = UiStyle::InactiveNick;
+  _uiStyleColorRoles["channel"] = UiStyle::Channel;
+  _uiStyleColorRoles["inactive-channel"] = UiStyle::InactiveChannel;
+  _uiStyleColorRoles["active-channel"] = UiStyle::ActiveChannel;
+  _uiStyleColorRoles["unread-channel"] = UiStyle::UnreadChannel;
+  _uiStyleColorRoles["highlighted-channel"] = UiStyle::HighlightedChannel;
+  _uiStyleColorRoles["query"] = UiStyle::Query;
+  _uiStyleColorRoles["inactive-query"] = UiStyle::InactiveQuery;
+  _uiStyleColorRoles["active-query"] = UiStyle::ActiveQuery;
+  _uiStyleColorRoles["unread-query"] = UiStyle::UnreadQuery;
+  _uiStyleColorRoles["highlighted-query"] = UiStyle::HighlightedQuery;
 }
 
 void QssParser::processStyleSheet(QString &ss) {
@@ -127,7 +143,7 @@ void QssParser::parseChatLineData(const QString &decl, const QString &contents)
     }
   }
 
-  _formats[fmtType] = format;
+  _formats[fmtType].merge(format);
 }
 
 quint64 QssParser::parseFormatType(const QString &decl) {
@@ -199,7 +215,7 @@ quint64 QssParser::parseFormatType(const QString &decl) {
   }
 
   // Next up: conditional (formats, labels, nickhash)
-  QRegExp condRx("\\s*(\\w+)\\s*=\\s*\"(\\w+)\"\\s*");
+  QRegExp condRx("\\s*([\\w\\-]+)\\s*=\\s*\"(\\w+)\"\\s*");
   if(!conditions.isEmpty()) {
     foreach(const QString &cond, conditions.split(',', QString::SkipEmptyParts)) {
       if(!condRx.exactMatch(cond)) {
@@ -212,6 +228,8 @@ quint64 QssParser::parseFormatType(const QString &decl) {
         quint64 labeltype = 0;
         if(condValue == "highlight")
           labeltype = UiStyle::Highlight;
+        else if(condValue == "selected")
+          labeltype = UiStyle::Selected;
         else {
           qWarning() << Q_FUNC_INFO << tr("Invalid message label: %1").arg(condValue);
           return UiStyle::Invalid;
@@ -236,19 +254,31 @@ quint64 QssParser::parseFormatType(const QString &decl) {
       } else if(condName == "format") {
         if(condValue == "bold")
           fmtType |= UiStyle::Bold;
-        if(condValue == "italic")
+        else if(condValue == "italic")
           fmtType |= UiStyle::Italic;
-        if(condValue == "underline")
+        else if(condValue == "underline")
           fmtType |= UiStyle::Underline;
-        if(condValue == "reverse")
+        else if(condValue == "reverse")
           fmtType |= UiStyle::Reverse;
         else {
           qWarning() << Q_FUNC_INFO << tr("Invalid format name: %1").arg(condValue);
           return UiStyle::Invalid;
         }
-
+      } else if(condName == "fg-color" || condName == "bg-color") {
+        bool ok;
+        quint8 col = condValue.toUInt(&ok, 16);
+        if(!ok || col > 0x0f) {
+          qWarning() << Q_FUNC_INFO << tr("Illegal IRC color specification (must be between 00 and 0f): %1").arg(condValue);
+          return UiStyle::Invalid;
+        }
+        if(condName == "fg-color")
+          fmtType |= 0x00400000 | (col << 24);
+        else
+          fmtType |= 0x00800000 | (col << 28);
+      } else {
+        qWarning() << Q_FUNC_INFO << tr("Unhandled condition: %1").arg(condName);
+        return UiStyle::Invalid;
       }
-      // TODO: colors
     }
   }
 
@@ -288,16 +318,18 @@ void QssParser::parsePaletteData(const QString &decl, const QString &contents) {
     }
     QString rolestr = line.left(idx).trimmed();
     QString brushstr = line.mid(idx + 1).trimmed();
-    if(!_paletteColorRoles.contains(rolestr)) {
-      qWarning() << Q_FUNC_INFO << tr("Unknown palette role name: %1").arg(rolestr);
-      continue;
-    }
-    QBrush brush = parseBrush(brushstr);
-    if(colorGroups.count()) {
-      foreach(QPalette::ColorGroup group, colorGroups)
-        _palette.setBrush(group, _paletteColorRoles.value(rolestr), brush);
+
+    if(_paletteColorRoles.contains(rolestr)) {
+      QBrush brush = parseBrush(brushstr);
+      if(colorGroups.count()) {
+        foreach(QPalette::ColorGroup group, colorGroups)
+          _palette.setBrush(group, _paletteColorRoles.value(rolestr), brush);
+      } else
+        _palette.setBrush(_paletteColorRoles.value(rolestr), brush);
+    } else if(_uiStyleColorRoles.contains(rolestr)) {
+      _uiStylePalette[_uiStyleColorRoles.value(rolestr)] = parseBrush(brushstr);
     } else
-      _palette.setBrush(_paletteColorRoles.value(rolestr), brush);
+      qWarning() << Q_FUNC_INFO << tr("Unknown palette role name: %1").arg(rolestr);
   }
 }
 
@@ -317,11 +349,12 @@ QBrush QssParser::parseBrush(const QString &str, bool *ok) {
       qWarning() << Q_FUNC_INFO << tr("Invalid palette color role specification: %1").arg(str);
       return QBrush();
     }
-    if(!_paletteColorRoles.contains(rx.cap(1))) {
-      qWarning() << Q_FUNC_INFO << tr("Unknown palette color role: %1").arg(rx.cap(1));
-      return QBrush();
-    }
-    return QBrush(_palette.brush(_paletteColorRoles.value(rx.cap(1))));
+    if(_paletteColorRoles.contains(rx.cap(1)))
+      return QBrush(_palette.brush(_paletteColorRoles.value(rx.cap(1))));
+    if(_uiStyleColorRoles.contains(rx.cap(1)))
+      return QBrush(_uiStylePalette.at(_uiStyleColorRoles.value(rx.cap(1))));
+    qWarning() << Q_FUNC_INFO << tr("Unknown palette color role: %1").arg(rx.cap(1));
+    return QBrush();
 
   } else if(str.startsWith("qlineargradient")) {
     static QString rxFloat("\\s*(-?\\s*[0-9]*\\.?[0-9]+)\\s*");
@@ -474,7 +507,7 @@ QGradientStops QssParser::parseGradientStops(const QString &str_) {
 /******** Font Properties ********/
 
 void QssParser::parseFont(const QString& value, QTextCharFormat* format) {
-  QRegExp rx("((?:(?:normal|italic|oblique|bold|100|200|300|400|500|600|700|800|900) ){0,2}) ?(\\d+)(pt|px)? \"(.*)\"");
+  QRegExp rx("((?:(?:normal|italic|oblique|underline|bold|100|200|300|400|500|600|700|800|900) ){0,2}) ?(\\d+)(pt|px)? \"(.*)\"");
   if(!rx.exactMatch(value)) {
     qWarning() << Q_FUNC_INFO << tr("Invalid font specification: %1").arg(value);
     return;
@@ -485,6 +518,8 @@ void QssParser::parseFont(const QString& value, QTextCharFormat* format) {
   foreach(QString prop, proplist) {
     if(prop == "italic")
       format->setFontItalic(true);
+    else if(prop == "underline")
+      format->setFontUnderline(true);
     //else if(prop == "oblique")
     //  format->setStyle(QFont::StyleOblique);
     else if(prop == "bold")
@@ -508,6 +543,8 @@ void QssParser::parseFontStyle(const QString& value, QTextCharFormat* format) {
     format->setFontItalic(false);
   else if(value == "italic")
     format->setFontItalic(true);
+  else if(value == "underline")
+    format->setFontUnderline(true);
   //else if(value == "oblique")
   //  format->setStyle(QFont::StyleOblique);
   else {