Event backend porting
[quassel.git] / src / uisupport / uistyle.cpp
index 281ec76..b08134b 100644 (file)
@@ -70,7 +70,10 @@ UiStyle::UiStyle(QObject *parent)
   // BufferView / NickView settings
   UiStyleSettings s;
   _showBufferViewIcons = _showNickViewIcons = s.value("ShowItemViewIcons", true).toBool();
-  s.notify("ShowItemViewIcons", this, SLOT(showItemViewIconsChanged()));
+  s.notify("ShowItemViewIcons", this, SLOT(showItemViewIconsChanged(QVariant)));
+
+  _allowMircColors = s.value("AllowMircColors", true).toBool();
+  s.notify("AllowMircColors", this, SLOT(allowMircColorsChanged(QVariant)));
 
   loadStyleSheet();
 }
@@ -92,7 +95,7 @@ void UiStyle::loadStyleSheet() {
   UiStyleSettings s;
 
   QString styleSheet;
-  styleSheet += loadStyleSheet("file:///" + Quassel::findDataFilePath("default.qss"));
+  styleSheet += loadStyleSheet("file:///" + Quassel::findDataFilePath("stylesheets/default.qss"));
   styleSheet += loadStyleSheet("file:///" + Quassel::configDirPath() + "settings.qss");
   if(s.value("UseCustomStyleSheet", false).toBool())
     styleSheet += loadStyleSheet("file:///" + s.value("CustomStyleSheetPath").toString(), true);
@@ -143,11 +146,15 @@ void UiStyle::setTimestampFormatString(const QString &format) {
   }
 }
 
+void UiStyle::allowMircColorsChanged(const QVariant &v) {
+  _allowMircColors = v.toBool();
+  emit changed();
+}
+
 /******** ItemView Styling *******/
 
-void UiStyle::showItemViewIconsChanged() {
-  UiStyleSettings s;
-  _showBufferViewIcons = _showNickViewIcons = s.value("ShowItemViewIcons").toBool();
+void UiStyle::showItemViewIconsChanged(const QVariant &v) {
+  _showBufferViewIcons = _showNickViewIcons = v.toBool();
 }
 
 QVariant UiStyle::bufferViewItemData(const QModelIndex &index, int role) const {
@@ -285,11 +292,11 @@ QTextCharFormat UiStyle::cachedFormat(quint32 formatType, quint32 messageLabel)
   return _formatCache.value(formatType | ((quint64)messageLabel << 32), QTextCharFormat());
 }
 
-void UiStyle::setCachedFormat(const QTextCharFormat &format, quint32 formatType, quint32 messageLabel) {
+void UiStyle::setCachedFormat(const QTextCharFormat &format, quint32 formatType, quint32 messageLabel) const {
   _formatCache[formatType | ((quint64)messageLabel << 32)] = format;
 }
 
-QFontMetricsF *UiStyle::fontMetrics(quint32 ftype, quint32 label) {
+QFontMetricsF *UiStyle::fontMetrics(quint32 ftype, quint32 label) const {
   // QFontMetricsF is not assignable, so we need to store pointers :/
   quint64 key = ftype | ((quint64)label << 32);
 
@@ -303,7 +310,7 @@ QFontMetricsF *UiStyle::fontMetrics(quint32 ftype, quint32 label) {
 
 // NOTE: This and the following functions are intimately tied to the values in FormatType. Don't change this
 //       until you _really_ know what you do!
-QTextCharFormat UiStyle::format(quint32 ftype, quint32 label_) {
+QTextCharFormat UiStyle::format(quint32 ftype, quint32 label_) const {
   if(ftype == Invalid)
     return QTextCharFormat();
 
@@ -325,7 +332,7 @@ QTextCharFormat UiStyle::format(quint32 ftype, quint32 label_) {
   return fmt;
 }
 
-void UiStyle::mergeFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) {
+void UiStyle::mergeFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) const {
   mergeSubElementFormat(fmt, ftype & 0x00ff, label);
 
   // TODO: allow combinations for mirc formats and colors (each), e.g. setting a special format for "bold and italic"
@@ -340,12 +347,14 @@ void UiStyle::mergeFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) {
 
   // Now we handle color codes
   // We assume that those can't be combined with subelement and message types.
-  if(ftype & 0x00400000)
-    mergeSubElementFormat(fmt, ftype & 0x0f400000, label); // foreground
-  if(ftype & 0x00800000)
-    mergeSubElementFormat(fmt, ftype & 0xf0800000, label); // background
-  if((ftype & 0x00c00000) == 0x00c00000)
-    mergeSubElementFormat(fmt, ftype & 0xffc00000, label); // combination
+  if(_allowMircColors) {
+    if(ftype & 0x00400000)
+      mergeSubElementFormat(fmt, ftype & 0x0f400000, label); // foreground
+    if(ftype & 0x00800000)
+      mergeSubElementFormat(fmt, ftype & 0xf0800000, label); // background
+    if((ftype & 0x00c00000) == 0x00c00000)
+      mergeSubElementFormat(fmt, ftype & 0xffc00000, label); // combination
+  }
 
   // URL
   if(ftype & Url)
@@ -353,7 +362,7 @@ void UiStyle::mergeFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) {
 }
 
 // Merge a subelement format into an existing message format
-void UiStyle::mergeSubElementFormat(QTextCharFormat& fmt, quint32 ftype, quint64 label) {
+void UiStyle::mergeSubElementFormat(QTextCharFormat& fmt, quint32 ftype, quint64 label) const {
   quint64 key = ftype | label;
   fmt.merge(format(key & Q_UINT64_C(0x0000ffffffffff00)));  // label + subelement
   fmt.merge(format(key & Q_UINT64_C(0x0000ffffffffffff)));  // label + subelement + msgtype
@@ -397,6 +406,8 @@ UiStyle::FormatType UiStyle::formatType(Message::Type msgType) {
       return NetsplitJoinMsg;
     case Message::NetsplitQuit:
       return NetsplitQuitMsg;
+    case Message::Invite:
+      return InviteMsg;
   }
   //Q_ASSERT(false); // we need to handle all message types
   qWarning() << Q_FUNC_INFO << "Unknown message type:" << msgType;
@@ -412,7 +423,7 @@ QString UiStyle::formatCode(FormatType ftype) {
   return _formatCodes.key(ftype);
 }
 
-QList<QTextLayout::FormatRange> UiStyle::toTextLayoutList(const FormatList &formatList, int textLength, quint32 messageLabel) {
+QList<QTextLayout::FormatRange> UiStyle::toTextLayoutList(const FormatList &formatList, int textLength, quint32 messageLabel) const {
   QList<QTextLayout::FormatRange> formatRanges;
   QTextLayout::FormatRange range;
   int i = 0;
@@ -475,6 +486,7 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat
       if(s[pos+1] == 'D') code += s[pos+2];
       FormatType ftype = formatType(code);
       if(ftype == Invalid) {
+        pos++;
         qWarning() << (QString("Invalid format code in string: %1").arg(s));
         continue;
       }
@@ -494,6 +506,7 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat
 QString UiStyle::mircToInternal(const QString &mirc_) {
   QString mirc = mirc_;
   mirc.replace('%', "%%");      // escape % just to be sure
+  mirc.replace('\t', "        ");      // tabs break layout, also this is italics in Konversation
   mirc.replace('\x02', "%B");
   mirc.replace('\x0f', "%O");
   mirc.replace('\x12', "%R");
@@ -552,6 +565,9 @@ void UiStyle::StyledMessage::style() const {
   QString txt = UiStyle::mircToInternal(contents());
   QString bufferName = bufferInfo().bufferName();
   bufferName.replace('%', "%%"); // well, you _can_ have a % in a buffername apparently... -_-
+  host.replace('%', "%%");       // hostnames too...
+  user.replace('%', "%%");       // and the username...
+  nick.replace('%', "%%");       // ... and then there's totally RFC-violating servers like justin.tv m(
   const int maxNetsplitNicks = 15;
 
   QString t;
@@ -616,7 +632,7 @@ void UiStyle::StyledMessage::style() const {
       //: Topic Message
       t = tr("%1").arg(txt); break;
     case Message::NetsplitJoin: {
-      QStringList users = txt.split(":");
+      QStringList users = txt.split("#:#");
       QStringList servers = users.takeLast().split(" ");
 
       for(int i = 0; i < users.count() && i < maxNetsplitNicks; i++)
@@ -630,7 +646,7 @@ void UiStyle::StyledMessage::style() const {
       }
       break;
     case Message::NetsplitQuit: {
-      QStringList users = txt.split(":");
+      QStringList users = txt.split("#:#");
       QStringList servers = users.takeLast().split(" ");
 
       for(int i = 0; i < users.count() && i < maxNetsplitNicks; i++)
@@ -644,6 +660,9 @@ void UiStyle::StyledMessage::style() const {
         t.append(tr("%DN%1%DN (%2 more)").arg(static_cast<QStringList>(users.mid(0, maxNetsplitNicks)).join(", ")).arg(users.count() - maxNetsplitNicks));
       }
       break;
+    case Message::Invite:
+      //: Invite Message
+      t = tr("%1").arg(txt); break;
     default:
       t = tr("[%1]").arg(txt);
   }
@@ -714,6 +733,8 @@ QString UiStyle::StyledMessage::decoratedSender() const {
       return tr("=>"); break;
     case Message::NetsplitQuit:
       return tr("<="); break;
+    case Message::Invite:
+      return tr("->"); break;
     default:
       return tr("%1").arg(plainSender());
   }