uistyle: Add more type-safety to UiStyle, and clean up a bit
authorManuel Nickschas <sputnick@quassel-irc.org>
Tue, 6 Mar 2018 20:07:42 +0000 (21:07 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Thu, 8 Mar 2018 01:10:28 +0000 (02:10 +0100)
Migrate all UiStyle enums to be enum classes. Enforce explicit types
instead of quint32 in most places using them, and handle MessageLabel
in a more obvious fashion. A bunch of bit-wise operators had to be
added to avoid lots of boilerplate when dealing with the enums.

FormatList now holds the formats in a struct rather than as plain enum
(or quint32) values. This will be needed for extended color support;
as the format type cannot hold the hard-coded extended color values,
the colors will be stored explicitly in the list and applied as
appropriate.

Also, in the quest to modernize the codebase, FormatList is now a
std::vector rather than a QList.

13 files changed:
src/qtui/chatitem.cpp
src/qtui/chatitem.h
src/qtui/chatline.cpp
src/qtui/chatlinemodelitem.cpp
src/qtui/chatlinemodelitem.h
src/qtui/markerlineitem.cpp
src/qtui/topicwidget.cpp
src/uisupport/qssparser.cpp
src/uisupport/qssparser.h
src/uisupport/styledlabel.cpp
src/uisupport/uisettings.cpp
src/uisupport/uistyle.cpp
src/uisupport/uistyle.h

index 4710639..e9922d2 100644 (file)
@@ -153,7 +153,7 @@ void ChatItem::initLayoutHelper(QTextLayout *layout, QTextOption::WrapMode wrapM
     layout->setTextOption(option);
 
     QList<QTextLayout::FormatRange> formatRanges
     layout->setTextOption(option);
 
     QList<QTextLayout::FormatRange> formatRanges
-        = QtUi::style()->toTextLayoutList(formatList(), layout->text().length(), data(ChatLineModel::MsgLabelRole).toUInt());
+        = QtUi::style()->toTextLayoutList(formatList(), layout->text().length(), data(ChatLineModel::MsgLabelRole).value<UiStyle::MessageLabel>());
     layout->setAdditionalFormats(formatRanges);
 }
 
     layout->setAdditionalFormats(formatRanges);
 }
 
@@ -257,11 +257,11 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
 }
 
 
 }
 
 
-void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, int start, int end, quint32 overlayFmt) const
+void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, quint16 start, quint16 end, UiStyle::FormatType overlayFmt) const
 {
 {
-    for (int i = 0; i < fmtList.count(); i++) {
+    for (size_t i = 0; i < fmtList.size(); i++) {
         int fmtStart = fmtList.at(i).first;
         int fmtStart = fmtList.at(i).first;
-        int fmtEnd = (i < fmtList.count()-1 ? fmtList.at(i+1).first : data(MessageModel::DisplayRole).toString().length());
+        int fmtEnd = (i < fmtList.size()-1 ? fmtList.at(i+1).first : data(MessageModel::DisplayRole).toString().length());
 
         if (fmtEnd <= start)
             continue;
 
         if (fmtEnd <= start)
             continue;
@@ -270,15 +270,15 @@ void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, int start, int end, q
 
         // split the format if necessary
         if (fmtStart < start) {
 
         // split the format if necessary
         if (fmtStart < start) {
-            fmtList.insert(i, fmtList.at(i));
+            fmtList.insert(fmtList.begin() + i, fmtList.at(i));
             fmtList[++i].first = start;
         }
         if (end < fmtEnd) {
             fmtList[++i].first = start;
         }
         if (end < fmtEnd) {
-            fmtList.insert(i, fmtList.at(i));
+            fmtList.insert(fmtList.begin() + i, fmtList.at(i));
             fmtList[i+1].first = end;
         }
 
             fmtList[i+1].first = end;
         }
 
-        fmtList[i].second |= overlayFmt;
+        fmtList[i].second.type |= overlayFmt;
     }
 }
 
     }
 }
 
@@ -306,15 +306,15 @@ QVector<QTextLayout::FormatRange> ChatItem::selectionFormats() const
 
     UiStyle::FormatList fmtList = formatList();
 
 
     UiStyle::FormatList fmtList = formatList();
 
-    while (fmtList.count() > 1 && fmtList.at(1).first <= start)
-        fmtList.removeFirst();
+    while (fmtList.size() > 1 && fmtList.at(1).first <= start)
+        fmtList.erase(fmtList.begin());
 
 
-    fmtList.first().first = start;
+    fmtList.front().first = start;
 
 
-    while (fmtList.count() > 1 && fmtList.last().first >= end)
-        fmtList.removeLast();
+    while (fmtList.size() > 1 && fmtList.back().first >= end)
+        fmtList.pop_back();
 
 
-    return QtUi::style()->toTextLayoutList(fmtList, end, UiStyle::Selected|data(ChatLineModel::MsgLabelRole).toUInt()).toVector();
+    return QtUi::style()->toTextLayoutList(fmtList, end, data(ChatLineModel::MsgLabelRole).value<UiStyle::MessageLabel>()|UiStyle::MessageLabel::Selected).toVector();
 }
 
 
 }
 
 
@@ -567,7 +567,7 @@ ContentsChatItem::ContentsChatItem(const QPointF &pos, const qreal &width, ChatL
 
 QFontMetricsF *ContentsChatItem::fontMetrics() const
 {
 
 QFontMetricsF *ContentsChatItem::fontMetrics() const
 {
-    return QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value<UiStyle::FormatList>().at(0).second, 0);
+    return QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value<UiStyle::FormatList>().at(0).second.type, UiStyle::MessageLabel::None);
 }
 
 
 }
 
 
@@ -674,7 +674,7 @@ UiStyle::FormatList ContentsChatItem::formatList() const
     for (int i = 0; i < privateData()->clickables.count(); i++) {
         Clickable click = privateData()->clickables.at(i);
         if (click.type() == Clickable::Url) {
     for (int i = 0; i < privateData()->clickables.count(); i++) {
         Clickable click = privateData()->clickables.at(i);
         if (click.type() == Clickable::Url) {
-            overlayFormat(fmtList, click.start(), click.start() + click.length(), UiStyle::Url);
+            overlayFormat(fmtList, click.start(), click.start() + click.length(), UiStyle::FormatType::Url);
         }
     }
     return fmtList;
         }
     }
     return fmtList;
index 7a2b562..2051fab 100644 (file)
@@ -114,7 +114,7 @@ protected:
     void paintBackground(QPainter *);
     QVector<QTextLayout::FormatRange> selectionFormats() const;
     virtual QVector<QTextLayout::FormatRange> additionalFormats() const;
     void paintBackground(QPainter *);
     QVector<QTextLayout::FormatRange> selectionFormats() const;
     virtual QVector<QTextLayout::FormatRange> additionalFormats() const;
-    void overlayFormat(UiStyle::FormatList &fmtList, int start, int end, quint32 overlayFmt) const;
+    void overlayFormat(UiStyle::FormatList &fmtList, quint16 start, quint16 end, UiStyle::FormatType overlayFmt) const;
 
     inline qint16 selectionStart() const { return _selectionStart; }
     inline void setSelectionStart(qint16 start) { _selectionStart = start; }
 
     inline qint16 selectionStart() const { return _selectionStart; }
     inline void setSelectionStart(qint16 start) { _selectionStart = start; }
index db23428..0c66622 100644 (file)
@@ -215,7 +215,7 @@ void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
     const QAbstractItemModel *model_ = model();
     QModelIndex myIdx = model_->index(row(), 0);
     Message::Type type = (Message::Type)myIdx.data(MessageModel::TypeRole).toInt();
     const QAbstractItemModel *model_ = model();
     QModelIndex myIdx = model_->index(row(), 0);
     Message::Type type = (Message::Type)myIdx.data(MessageModel::TypeRole).toInt();
-    UiStyle::MessageLabel label = (UiStyle::MessageLabel)myIdx.data(ChatLineModel::MsgLabelRole).toInt();
+    UiStyle::MessageLabel label = myIdx.data(ChatLineModel::MsgLabelRole).value<UiStyle::MessageLabel>();
 
     QTextCharFormat msgFmt = QtUi::style()->format(UiStyle::formatType(type), label);
     if (msgFmt.hasProperty(QTextFormat::BackgroundBrush)) {
 
     QTextCharFormat msgFmt = QtUi::style()->format(UiStyle::formatType(type), label);
     if (msgFmt.hasProperty(QTextFormat::BackgroundBrush)) {
@@ -223,7 +223,7 @@ void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
     }
 
     if (_selection & Selected) {
     }
 
     if (_selection & Selected) {
-        QTextCharFormat selFmt = QtUi::style()->format(UiStyle::formatType(type), label | UiStyle::Selected);
+        QTextCharFormat selFmt = QtUi::style()->format(UiStyle::formatType(type), label | UiStyle::MessageLabel::Selected);
         if (selFmt.hasProperty(QTextFormat::BackgroundBrush)) {
             qreal left = item((ChatLineModel::ColumnType)(_selection & ItemMask))->pos().x();
             QRectF selectRect(left, 0, width() - left, height());
         if (selFmt.hasProperty(QTextFormat::BackgroundBrush)) {
             qreal left = item((ChatLineModel::ColumnType)(_selection & ItemMask))->pos().x();
             QRectF selectRect(left, 0, width() - left, height());
index 5000221..5582fe8 100644 (file)
@@ -76,7 +76,7 @@ bool ChatLineModelItem::setData(int column, const QVariant &value, int role)
 QVariant ChatLineModelItem::data(int column, int role) const
 {
     if (role == ChatLineModel::MsgLabelRole)
 QVariant ChatLineModelItem::data(int column, int role) const
 {
     if (role == ChatLineModel::MsgLabelRole)
-        return messageLabel();
+        return QVariant::fromValue<UiStyle::MessageLabel>(messageLabel());
 
     QVariant variant;
     MessageModel::ColumnType col = (MessageModel::ColumnType)column;
 
     QVariant variant;
     MessageModel::ColumnType col = (MessageModel::ColumnType)column;
@@ -107,12 +107,11 @@ QVariant ChatLineModelItem::timestampData(int role) const
     case ChatLineModel::EditRole:
         return _styledMsg.timestamp();
     case ChatLineModel::BackgroundRole:
     case ChatLineModel::EditRole:
         return _styledMsg.timestamp();
     case ChatLineModel::BackgroundRole:
-        return backgroundBrush(UiStyle::Timestamp);
+        return backgroundBrush(UiStyle::FormatType::Timestamp);
     case ChatLineModel::SelectedBackgroundRole:
     case ChatLineModel::SelectedBackgroundRole:
-        return backgroundBrush(UiStyle::Timestamp, true);
+        return backgroundBrush(UiStyle::FormatType::Timestamp, true);
     case ChatLineModel::FormatRole:
     case ChatLineModel::FormatRole:
-        return QVariant::fromValue<UiStyle::FormatList>(UiStyle::FormatList()
-                                                        << qMakePair((quint16)0, (quint32) UiStyle::formatType(_styledMsg.type()) | UiStyle::Timestamp));
+        return QVariant::fromValue<UiStyle::FormatList>({std::make_pair(quint16{0}, UiStyle::Format{UiStyle::formatType(_styledMsg.type()) | UiStyle::FormatType::Timestamp})});
     }
     return QVariant();
 }
     }
     return QVariant();
 }
@@ -126,12 +125,11 @@ QVariant ChatLineModelItem::senderData(int role) const
     case ChatLineModel::EditRole:
         return _styledMsg.plainSender();
     case ChatLineModel::BackgroundRole:
     case ChatLineModel::EditRole:
         return _styledMsg.plainSender();
     case ChatLineModel::BackgroundRole:
-        return backgroundBrush(UiStyle::Sender);
+        return backgroundBrush(UiStyle::FormatType::Sender);
     case ChatLineModel::SelectedBackgroundRole:
     case ChatLineModel::SelectedBackgroundRole:
-        return backgroundBrush(UiStyle::Sender, true);
+        return backgroundBrush(UiStyle::FormatType::Sender, true);
     case ChatLineModel::FormatRole:
     case ChatLineModel::FormatRole:
-        return QVariant::fromValue<UiStyle::FormatList>(UiStyle::FormatList()
-                                                        << qMakePair((quint16)0, (quint32) UiStyle::formatType(_styledMsg.type()) | UiStyle::Sender));
+        return QVariant::fromValue<UiStyle::FormatList>({std::make_pair(quint16{0}, UiStyle::Format{UiStyle::formatType(_styledMsg.type()) | UiStyle::FormatType::Sender})});
     }
     return QVariant();
 }
     }
     return QVariant();
 }
@@ -144,9 +142,9 @@ QVariant ChatLineModelItem::contentsData(int role) const
     case ChatLineModel::EditRole:
         return _styledMsg.plainContents();
     case ChatLineModel::BackgroundRole:
     case ChatLineModel::EditRole:
         return _styledMsg.plainContents();
     case ChatLineModel::BackgroundRole:
-        return backgroundBrush(UiStyle::Contents);
+        return backgroundBrush(UiStyle::FormatType::Contents);
     case ChatLineModel::SelectedBackgroundRole:
     case ChatLineModel::SelectedBackgroundRole:
-        return backgroundBrush(UiStyle::Contents, true);
+        return backgroundBrush(UiStyle::FormatType::Contents, true);
     case ChatLineModel::FormatRole:
         return QVariant::fromValue<UiStyle::FormatList>(_styledMsg.contentsFormatList());
     case ChatLineModel::WrapListRole:
     case ChatLineModel::FormatRole:
         return QVariant::fromValue<UiStyle::FormatList>(_styledMsg.contentsFormatList());
     case ChatLineModel::WrapListRole:
@@ -158,20 +156,23 @@ QVariant ChatLineModelItem::contentsData(int role) const
 }
 
 
 }
 
 
-quint32 ChatLineModelItem::messageLabel() const
+UiStyle::MessageLabel ChatLineModelItem::messageLabel() const
 {
 {
-    quint32 label = _styledMsg.senderHash() << 16;
+    using MessageLabel = UiStyle::MessageLabel;
+
+    MessageLabel label = static_cast<MessageLabel>(_styledMsg.senderHash() << 16);
     if (_styledMsg.flags() & Message::Self)
     if (_styledMsg.flags() & Message::Self)
-        label |= UiStyle::OwnMsg;
+        label |= MessageLabel::OwnMsg;
     if (_styledMsg.flags() & Message::Highlight)
     if (_styledMsg.flags() & Message::Highlight)
-        label |= UiStyle::Highlight;
+        label |= MessageLabel::Highlight;
     return label;
 }
 
 
 QVariant ChatLineModelItem::backgroundBrush(UiStyle::FormatType subelement, bool selected) const
 {
     return label;
 }
 
 
 QVariant ChatLineModelItem::backgroundBrush(UiStyle::FormatType subelement, bool selected) const
 {
-    QTextCharFormat fmt = QtUi::style()->format(UiStyle::formatType(_styledMsg.type()) | subelement, messageLabel() | (selected ? UiStyle::Selected : 0));
+    QTextCharFormat fmt = QtUi::style()->format(UiStyle::formatType(_styledMsg.type()) | subelement,
+                                                messageLabel() | (selected ? UiStyle::MessageLabel::Selected : UiStyle::MessageLabel::None));
     if (fmt.hasProperty(QTextFormat::BackgroundBrush))
         return QVariant::fromValue<QBrush>(fmt.background());
     return QVariant();
     if (fmt.hasProperty(QTextFormat::BackgroundBrush))
         return QVariant::fromValue<QBrush>(fmt.background());
     return QVariant();
index 5e03e0c..e48b1cd 100644 (file)
@@ -18,8 +18,7 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
-#ifndef CHATLINEMODELITEM_H_
-#define CHATLINEMODELITEM_H_
+#pragma once
 
 #include "messagemodel.h"
 
 
 #include "messagemodel.h"
 
@@ -58,7 +57,7 @@ private:
     QVariant contentsData(int role) const;
 
     QVariant backgroundBrush(UiStyle::FormatType subelement, bool selected = false) const;
     QVariant contentsData(int role) const;
 
     QVariant backgroundBrush(UiStyle::FormatType subelement, bool selected = false) const;
-    quint32 messageLabel() const;
+    UiStyle::MessageLabel messageLabel() const;
 
     void computeWrapList() const;
 
 
     void computeWrapList() const;
 
@@ -68,6 +67,3 @@ private:
     static unsigned char *TextBoundaryFinderBuffer;
     static int TextBoundaryFinderBufferSize;
 };
     static unsigned char *TextBoundaryFinderBuffer;
     static int TextBoundaryFinderBufferSize;
 };
-
-
-#endif
index 3336341..68d681a 100644 (file)
@@ -45,13 +45,13 @@ void MarkerLineItem::setChatLine(ChatLine *line)
 
 void MarkerLineItem::styleChanged()
 {
 
 void MarkerLineItem::styleChanged()
 {
-    _brush = QtUi::style()->brush(UiStyle::MarkerLine);
+    _brush = QtUi::style()->brush(UiStyle::ColorRole::MarkerLine);
 
     // if this is a solid color, we assume 1px because wesurely  don't surely don't want to fill the entire chatline.
     // else, use the height of a single line of text to play around with gradients etc.
     qreal height = 1.;
     if (_brush.style() != Qt::SolidPattern)
 
     // if this is a solid color, we assume 1px because wesurely  don't surely don't want to fill the entire chatline.
     // else, use the height of a single line of text to play around with gradients etc.
     qreal height = 1.;
     if (_brush.style() != Qt::SolidPattern)
-        height = QtUi::style()->fontMetrics(QtUiStyle::PlainMsg, 0)->lineSpacing();
+        height = QtUi::style()->fontMetrics(QtUiStyle::FormatType::PlainMsg, UiStyle::MessageLabel::None)->lineSpacing();
 
     prepareGeometryChange();
     _boundingRect = QRectF(0, 0, scene() ? scene()->width() : 100, height);
 
     prepareGeometryChange();
     _boundingRect = QRectF(0, 0, scene() ? scene()->width() : 100, height);
index b449f12..712e74c 100644 (file)
@@ -202,7 +202,7 @@ void TopicWidget::updateResizeMode()
 void TopicWidget::clickableActivated(const Clickable &click)
 {
     NetworkId networkId = selectionModel()->currentIndex().data(NetworkModel::NetworkIdRole).value<NetworkId>();
 void TopicWidget::clickableActivated(const Clickable &click)
 {
     NetworkId networkId = selectionModel()->currentIndex().data(NetworkModel::NetworkIdRole).value<NetworkId>();
-    UiStyle::StyledString sstr = GraphicalUi::uiStyle()->styleString(GraphicalUi::uiStyle()->mircToInternal(_topic), UiStyle::PlainMsg);
+    UiStyle::StyledString sstr = GraphicalUi::uiStyle()->styleString(GraphicalUi::uiStyle()->mircToInternal(_topic), UiStyle::FormatType::PlainMsg);
     click.activate(networkId, sstr.plainText);
 }
 
     click.activate(networkId, sstr.plainText);
 }
 
index 50c8c32..24032fb 100644 (file)
@@ -18,6 +18,9 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
+#include <tuple>
+#include <utility>
+
 #include <QApplication>
 
 #include "qssparser.h"
 #include <QApplication>
 
 #include "qssparser.h"
@@ -49,27 +52,27 @@ QssParser::QssParser()
     _paletteColorRoles["window"] = QPalette::Window;
     _paletteColorRoles["window-text"] = QPalette::WindowText;
 
     _paletteColorRoles["window"] = QPalette::Window;
     _paletteColorRoles["window-text"] = QPalette::WindowText;
 
-    _uiStylePalette = QVector<QBrush>(UiStyle::NumRoles, QBrush());
+    _uiStylePalette = QVector<QBrush>(static_cast<int>(UiStyle::ColorRole::NumRoles), QBrush());
 
 
-    _uiStyleColorRoles["marker-line"] = UiStyle::MarkerLine;
+    _uiStyleColorRoles["marker-line"] = UiStyle::ColorRole::MarkerLine;
     // Sender colors
     // Sender colors
-    _uiStyleColorRoles["sender-color-self"] = UiStyle::SenderColorSelf;
-    _uiStyleColorRoles["sender-color-00"] = UiStyle::SenderColor00;
-    _uiStyleColorRoles["sender-color-01"] = UiStyle::SenderColor01;
-    _uiStyleColorRoles["sender-color-02"] = UiStyle::SenderColor02;
-    _uiStyleColorRoles["sender-color-03"] = UiStyle::SenderColor03;
-    _uiStyleColorRoles["sender-color-04"] = UiStyle::SenderColor04;
-    _uiStyleColorRoles["sender-color-05"] = UiStyle::SenderColor05;
-    _uiStyleColorRoles["sender-color-06"] = UiStyle::SenderColor06;
-    _uiStyleColorRoles["sender-color-07"] = UiStyle::SenderColor07;
-    _uiStyleColorRoles["sender-color-08"] = UiStyle::SenderColor08;
-    _uiStyleColorRoles["sender-color-09"] = UiStyle::SenderColor09;
-    _uiStyleColorRoles["sender-color-0a"] = UiStyle::SenderColor0a;
-    _uiStyleColorRoles["sender-color-0b"] = UiStyle::SenderColor0b;
-    _uiStyleColorRoles["sender-color-0c"] = UiStyle::SenderColor0c;
-    _uiStyleColorRoles["sender-color-0d"] = UiStyle::SenderColor0d;
-    _uiStyleColorRoles["sender-color-0e"] = UiStyle::SenderColor0e;
-    _uiStyleColorRoles["sender-color-0f"] = UiStyle::SenderColor0f;
+    _uiStyleColorRoles["sender-color-self"] = UiStyle::ColorRole::SenderColorSelf;
+    _uiStyleColorRoles["sender-color-00"] = UiStyle::ColorRole::SenderColor00;
+    _uiStyleColorRoles["sender-color-01"] = UiStyle::ColorRole::SenderColor01;
+    _uiStyleColorRoles["sender-color-02"] = UiStyle::ColorRole::SenderColor02;
+    _uiStyleColorRoles["sender-color-03"] = UiStyle::ColorRole::SenderColor03;
+    _uiStyleColorRoles["sender-color-04"] = UiStyle::ColorRole::SenderColor04;
+    _uiStyleColorRoles["sender-color-05"] = UiStyle::ColorRole::SenderColor05;
+    _uiStyleColorRoles["sender-color-06"] = UiStyle::ColorRole::SenderColor06;
+    _uiStyleColorRoles["sender-color-07"] = UiStyle::ColorRole::SenderColor07;
+    _uiStyleColorRoles["sender-color-08"] = UiStyle::ColorRole::SenderColor08;
+    _uiStyleColorRoles["sender-color-09"] = UiStyle::ColorRole::SenderColor09;
+    _uiStyleColorRoles["sender-color-0a"] = UiStyle::ColorRole::SenderColor0a;
+    _uiStyleColorRoles["sender-color-0b"] = UiStyle::ColorRole::SenderColor0b;
+    _uiStyleColorRoles["sender-color-0c"] = UiStyle::ColorRole::SenderColor0c;
+    _uiStyleColorRoles["sender-color-0d"] = UiStyle::ColorRole::SenderColor0d;
+    _uiStyleColorRoles["sender-color-0e"] = UiStyle::ColorRole::SenderColor0e;
+    _uiStyleColorRoles["sender-color-0f"] = UiStyle::ColorRole::SenderColor0f;
 }
 
 
 }
 
 
@@ -79,12 +82,12 @@ void QssParser::processStyleSheet(QString &ss)
         return;
 
     // Remove C-style comments /* */ or //
         return;
 
     // Remove C-style comments /* */ or //
-    QRegExp commentRx("(//.*(\\n|$)|/\\*.*\\*/)");
+    static QRegExp commentRx("(//.*(\\n|$)|/\\*.*\\*/)");
     commentRx.setMinimal(true);
     ss.remove(commentRx);
 
     // Palette definitions first, so we can apply roles later on
     commentRx.setMinimal(true);
     ss.remove(commentRx);
 
     // Palette definitions first, so we can apply roles later on
-    QRegExp paletterx("(Palette[^{]*)\\{([^}]+)\\}");
+    static const QRegExp paletterx("(Palette[^{]*)\\{([^}]+)\\}");
     int pos = 0;
     while ((pos = paletterx.indexIn(ss, pos)) >= 0) {
         parsePaletteBlock(paletterx.cap(1).trimmed(), paletterx.cap(2).trimmed());
     int pos = 0;
     while ((pos = paletterx.indexIn(ss, pos)) >= 0) {
         parsePaletteBlock(paletterx.cap(1).trimmed(), paletterx.cap(2).trimmed());
@@ -92,7 +95,7 @@ void QssParser::processStyleSheet(QString &ss)
     }
 
     // Now we can parse the rest of our custom blocks
     }
 
     // Now we can parse the rest of our custom blocks
-    QRegExp blockrx("((?:ChatLine|ChatListItem|NickListItem)[^{]*)\\{([^}]+)\\}");
+    static const QRegExp blockrx("((?:ChatLine|ChatListItem|NickListItem)[^{]*)\\{([^}]+)\\}");
     pos = 0;
     while ((pos = blockrx.indexIn(ss, pos)) >= 0) {
         //qDebug() << blockrx.cap(1) << blockrx.cap(2);
     pos = 0;
     while ((pos = blockrx.indexIn(ss, pos)) >= 0) {
         //qDebug() << blockrx.cap(1) << blockrx.cap(2);
@@ -115,18 +118,20 @@ void QssParser::processStyleSheet(QString &ss)
 
 void QssParser::parseChatLineBlock(const QString &decl, const QString &contents)
 {
 
 void QssParser::parseChatLineBlock(const QString &decl, const QString &contents)
 {
-    quint64 fmtType = parseFormatType(decl);
-    if (fmtType == UiStyle::Invalid)
+    UiStyle::FormatType fmtType;
+    UiStyle::MessageLabel label;
+    std::tie(fmtType, label) = parseFormatType(decl);
+    if (fmtType == UiStyle::FormatType::Invalid)
         return;
 
         return;
 
-    _formats[fmtType].merge(parseFormat(contents));
+    _formats[fmtType|label].merge(parseFormat(contents));
 }
 
 
 void QssParser::parseListItemBlock(const QString &decl, const QString &contents)
 {
 }
 
 
 void QssParser::parseListItemBlock(const QString &decl, const QString &contents)
 {
-    quint32 fmtType = parseItemFormatType(decl);
-    if (fmtType == UiStyle::Invalid)
+    UiStyle::ItemFormatType fmtType = parseItemFormatType(decl);
+    if (fmtType == UiStyle::ItemFormatType::Invalid)
         return;
 
     _listItemFormats[fmtType].merge(parseFormat(contents));
         return;
 
     _listItemFormats[fmtType].merge(parseFormat(contents));
@@ -141,7 +146,7 @@ void QssParser::parsePaletteBlock(const QString &decl, const QString &contents)
     QList<QPalette::ColorGroup> colorGroups;
 
     // Check if we want to apply this palette definition for particular ColorGroups
     QList<QPalette::ColorGroup> colorGroups;
 
     // Check if we want to apply this palette definition for particular ColorGroups
-    QRegExp rx("Palette((:(normal|active|inactive|disabled))*)");
+    static const QRegExp rx("Palette((:(normal|active|inactive|disabled))*)");
     if (!rx.exactMatch(decl)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid block declaration: %1").arg(decl);
         return;
     if (!rx.exactMatch(decl)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid block declaration: %1").arg(decl);
         return;
@@ -178,7 +183,7 @@ void QssParser::parsePaletteBlock(const QString &decl, const QString &contents)
                 _palette.setBrush(_paletteColorRoles.value(rolestr), brush);
         }
         else if (_uiStyleColorRoles.contains(rolestr)) {
                 _palette.setBrush(_paletteColorRoles.value(rolestr), brush);
         }
         else if (_uiStyleColorRoles.contains(rolestr)) {
-            _uiStylePalette[_uiStyleColorRoles.value(rolestr)] = parseBrush(brushstr);
+            _uiStylePalette[static_cast<int>(_uiStyleColorRoles.value(rolestr))] = parseBrush(brushstr);
         }
         else
             qWarning() << Q_FUNC_INFO << tr("Unknown palette role name: %1").arg(rolestr);
         }
         else
             qWarning() << Q_FUNC_INFO << tr("Unknown palette role name: %1").arg(rolestr);
@@ -188,184 +193,190 @@ void QssParser::parsePaletteBlock(const QString &decl, const QString &contents)
 
 /******** Determine format types from a block declaration ********/
 
 
 /******** Determine format types from a block declaration ********/
 
-quint64 QssParser::parseFormatType(const QString &decl)
+std::pair<UiStyle::FormatType, UiStyle::MessageLabel> QssParser::parseFormatType(const QString &decl)
 {
 {
-    QRegExp rx("ChatLine(?:::(\\w+))?(?:#([\\w\\-]+))?(?:\\[([=-,\\\"\\w\\s]+)\\])?");
+    using FormatType = UiStyle::FormatType;
+    using MessageLabel = UiStyle::MessageLabel;
+
+    const std::pair<UiStyle::FormatType, UiStyle::MessageLabel> invalid{FormatType::Invalid, MessageLabel::None};
+
+    static const QRegExp rx("ChatLine(?:::(\\w+))?(?:#([\\w\\-]+))?(?:\\[([=-,\\\"\\w\\s]+)\\])?");
     // $1: subelement; $2: msgtype; $3: conditionals
     if (!rx.exactMatch(decl)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid block declaration: %1").arg(decl);
     // $1: subelement; $2: msgtype; $3: conditionals
     if (!rx.exactMatch(decl)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid block declaration: %1").arg(decl);
-        return UiStyle::Invalid;
+        return invalid;
     }
     QString subElement = rx.cap(1);
     QString msgType = rx.cap(2);
     QString conditions = rx.cap(3);
 
     }
     QString subElement = rx.cap(1);
     QString msgType = rx.cap(2);
     QString conditions = rx.cap(3);
 
-    quint64 fmtType = 0;
+    FormatType fmtType{FormatType::Base};
+    MessageLabel label{MessageLabel::None};
 
     // First determine the subelement
     if (!subElement.isEmpty()) {
         if (subElement == "timestamp")
 
     // First determine the subelement
     if (!subElement.isEmpty()) {
         if (subElement == "timestamp")
-            fmtType |= UiStyle::Timestamp;
+            fmtType |= FormatType::Timestamp;
         else if (subElement == "sender")
         else if (subElement == "sender")
-            fmtType |= UiStyle::Sender;
+            fmtType |= FormatType::Sender;
         else if (subElement == "nick")
         else if (subElement == "nick")
-            fmtType |= UiStyle::Nick;
+            fmtType |= FormatType::Nick;
         else if (subElement == "contents")
         else if (subElement == "contents")
-            fmtType |= UiStyle::Contents;
+            fmtType |= FormatType::Contents;
         else if (subElement == "hostmask")
         else if (subElement == "hostmask")
-            fmtType |= UiStyle::Hostmask;
+            fmtType |= FormatType::Hostmask;
         else if (subElement == "modeflags")
         else if (subElement == "modeflags")
-            fmtType |= UiStyle::ModeFlags;
+            fmtType |= FormatType::ModeFlags;
         else if (subElement == "url")
         else if (subElement == "url")
-            fmtType |= UiStyle::Url;
+            fmtType |= FormatType::Url;
         else {
             qWarning() << Q_FUNC_INFO << tr("Invalid subelement name in %1").arg(decl);
         else {
             qWarning() << Q_FUNC_INFO << tr("Invalid subelement name in %1").arg(decl);
-            return UiStyle::Invalid;
+            return invalid;
         }
     }
 
     // Now, figure out the message type
     if (!msgType.isEmpty()) {
         if (msgType == "plain")
         }
     }
 
     // Now, figure out the message type
     if (!msgType.isEmpty()) {
         if (msgType == "plain")
-            fmtType |= UiStyle::PlainMsg;
+            fmtType |= FormatType::PlainMsg;
         else if (msgType == "notice")
         else if (msgType == "notice")
-            fmtType |= UiStyle::NoticeMsg;
+            fmtType |= FormatType::NoticeMsg;
         else if (msgType == "action")
         else if (msgType == "action")
-            fmtType |= UiStyle::ActionMsg;
+            fmtType |= FormatType::ActionMsg;
         else if (msgType == "nick")
         else if (msgType == "nick")
-            fmtType |= UiStyle::NickMsg;
+            fmtType |= FormatType::NickMsg;
         else if (msgType == "mode")
         else if (msgType == "mode")
-            fmtType |= UiStyle::ModeMsg;
+            fmtType |= FormatType::ModeMsg;
         else if (msgType == "join")
         else if (msgType == "join")
-            fmtType |= UiStyle::JoinMsg;
+            fmtType |= FormatType::JoinMsg;
         else if (msgType == "part")
         else if (msgType == "part")
-            fmtType |= UiStyle::PartMsg;
+            fmtType |= FormatType::PartMsg;
         else if (msgType == "quit")
         else if (msgType == "quit")
-            fmtType |= UiStyle::QuitMsg;
+            fmtType |= FormatType::QuitMsg;
         else if (msgType == "kick")
         else if (msgType == "kick")
-            fmtType |= UiStyle::KickMsg;
+            fmtType |= FormatType::KickMsg;
         else if (msgType == "kill")
         else if (msgType == "kill")
-            fmtType |= UiStyle::KillMsg;
+            fmtType |= FormatType::KillMsg;
         else if (msgType == "server")
         else if (msgType == "server")
-            fmtType |= UiStyle::ServerMsg;
+            fmtType |= FormatType::ServerMsg;
         else if (msgType == "info")
         else if (msgType == "info")
-            fmtType |= UiStyle::InfoMsg;
+            fmtType |= FormatType::InfoMsg;
         else if (msgType == "error")
         else if (msgType == "error")
-            fmtType |= UiStyle::ErrorMsg;
+            fmtType |= FormatType::ErrorMsg;
         else if (msgType == "daychange")
         else if (msgType == "daychange")
-            fmtType |= UiStyle::DayChangeMsg;
+            fmtType |= FormatType::DayChangeMsg;
         else if (msgType == "topic")
         else if (msgType == "topic")
-            fmtType |= UiStyle::TopicMsg;
+            fmtType |= FormatType::TopicMsg;
         else if (msgType == "netsplit-join")
         else if (msgType == "netsplit-join")
-            fmtType |= UiStyle::NetsplitJoinMsg;
+            fmtType |= FormatType::NetsplitJoinMsg;
         else if (msgType == "netsplit-quit")
         else if (msgType == "netsplit-quit")
-            fmtType |= UiStyle::NetsplitQuitMsg;
+            fmtType |= FormatType::NetsplitQuitMsg;
         else if (msgType == "invite")
         else if (msgType == "invite")
-            fmtType |= UiStyle::InviteMsg;
+            fmtType |= FormatType::InviteMsg;
         else {
             qWarning() << Q_FUNC_INFO << tr("Invalid message type in %1").arg(decl);
         }
     }
 
     // Next up: conditional (formats, labels, nickhash)
         else {
             qWarning() << Q_FUNC_INFO << tr("Invalid message type in %1").arg(decl);
         }
     }
 
     // Next up: conditional (formats, labels, nickhash)
-    QRegExp condRx("\\s*([\\w\\-]+)\\s*=\\s*\"(\\w+)\"\\s*");
+    static const QRegExp condRx("\\s*([\\w\\-]+)\\s*=\\s*\"(\\w+)\"\\s*");
     if (!conditions.isEmpty()) {
         foreach(const QString &cond, conditions.split(',', QString::SkipEmptyParts)) {
             if (!condRx.exactMatch(cond)) {
                 qWarning() << Q_FUNC_INFO << tr("Invalid condition %1").arg(cond);
     if (!conditions.isEmpty()) {
         foreach(const QString &cond, conditions.split(',', QString::SkipEmptyParts)) {
             if (!condRx.exactMatch(cond)) {
                 qWarning() << Q_FUNC_INFO << tr("Invalid condition %1").arg(cond);
-                return UiStyle::Invalid;
+                return invalid;
             }
             QString condName = condRx.cap(1);
             QString condValue = condRx.cap(2);
             if (condName == "label") {
             }
             QString condName = condRx.cap(1);
             QString condValue = condRx.cap(2);
             if (condName == "label") {
-                quint64 labeltype = 0;
                 if (condValue == "highlight")
                 if (condValue == "highlight")
-                    labeltype = UiStyle::Highlight;
+                    label |= MessageLabel::Highlight;
                 else if (condValue == "selected")
                 else if (condValue == "selected")
-                    labeltype = UiStyle::Selected;
+                    label |= MessageLabel::Selected;
                 else {
                     qWarning() << Q_FUNC_INFO << tr("Invalid message label: %1").arg(condValue);
                 else {
                     qWarning() << Q_FUNC_INFO << tr("Invalid message label: %1").arg(condValue);
-                    return UiStyle::Invalid;
+                    return invalid;
                 }
                 }
-                fmtType |= (labeltype << 32);
             }
             else if (condName == "sender") {
                 if (condValue == "self")
             }
             else if (condName == "sender") {
                 if (condValue == "self")
-                    fmtType |= (quint64) UiStyle::OwnMsg << 32;  // sender="self" is actually treated as a label
+                    label |= MessageLabel::OwnMsg;  // sender="self" is actually treated as a label
                 else {
                     bool ok = true;
                 else {
                     bool ok = true;
-                    quint64 val = condValue.toUInt(&ok, 16);
+                    quint32 val = condValue.toUInt(&ok, 16);
                     if (!ok) {
                         qWarning() << Q_FUNC_INFO << tr("Invalid senderhash specification: %1").arg(condValue);
                     if (!ok) {
                         qWarning() << Q_FUNC_INFO << tr("Invalid senderhash specification: %1").arg(condValue);
-                        return UiStyle::Invalid;
+                        return invalid;
                     }
                     if (val >= 16) {
                         qWarning() << Q_FUNC_INFO << tr("Senderhash can be at most \"0x0f\"!");
                     }
                     if (val >= 16) {
                         qWarning() << Q_FUNC_INFO << tr("Senderhash can be at most \"0x0f\"!");
-                        return UiStyle::Invalid;
+                        return invalid;
                     }
                     }
-                    fmtType |= ++val << 48;
+                    label |= static_cast<MessageLabel>(++val << 16);
                 }
             }
             else if (condName == "format") {
                 if (condValue == "bold")
                 }
             }
             else if (condName == "format") {
                 if (condValue == "bold")
-                    fmtType |= UiStyle::Bold;
+                    fmtType |= FormatType::Bold;
                 else if (condValue == "italic")
                 else if (condValue == "italic")
-                    fmtType |= UiStyle::Italic;
+                    fmtType |= FormatType::Italic;
                 else if (condValue == "underline")
                 else if (condValue == "underline")
-                    fmtType |= UiStyle::Underline;
+                    fmtType |= FormatType::Underline;
                 else if (condValue == "reverse")
                 else if (condValue == "reverse")
-                    fmtType |= UiStyle::Reverse;
+                    fmtType |= FormatType::Reverse;
                 else {
                     qWarning() << Q_FUNC_INFO << tr("Invalid format name: %1").arg(condValue);
                 else {
                     qWarning() << Q_FUNC_INFO << tr("Invalid format name: %1").arg(condValue);
-                    return UiStyle::Invalid;
+                    return invalid;
                 }
             }
             else if (condName == "fg-color" || condName == "bg-color") {
                 bool ok;
                 }
             }
             else if (condName == "fg-color" || condName == "bg-color") {
                 bool ok;
-                quint8 col = condValue.toUInt(&ok, 16);
+                quint32 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);
                 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;
+                    return invalid;
                 }
                 if (condName == "fg-color")
                 }
                 if (condName == "fg-color")
-                    fmtType |= 0x00400000 | (quint32)(col << 24);
+                    fmtType |= 0x00400000 | (col << 24);
                 else
                 else
-                    fmtType |= 0x00800000 | (quint32)(col << 28);
+                    fmtType |= 0x00800000 | (col << 28);
             }
             else {
                 qWarning() << Q_FUNC_INFO << tr("Unhandled condition: %1").arg(condName);
             }
             else {
                 qWarning() << Q_FUNC_INFO << tr("Unhandled condition: %1").arg(condName);
-                return UiStyle::Invalid;
+                return invalid;
             }
         }
     }
 
             }
         }
     }
 
-    return fmtType;
+    return std::make_pair(fmtType, label);
 }
 
 
 // FIXME: Code duplication
 }
 
 
 // FIXME: Code duplication
-quint32 QssParser::parseItemFormatType(const QString &decl)
+UiStyle::ItemFormatType QssParser::parseItemFormatType(const QString &decl)
 {
 {
-    QRegExp rx("(Chat|Nick)ListItem(?:\\[([=-,\\\"\\w\\s]+)\\])?");
+    using ItemFormatType = UiStyle::ItemFormatType;
+
+    static const QRegExp rx("(Chat|Nick)ListItem(?:\\[([=-,\\\"\\w\\s]+)\\])?");
     // $1: item type; $2: properties
     if (!rx.exactMatch(decl)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid block declaration: %1").arg(decl);
     // $1: item type; $2: properties
     if (!rx.exactMatch(decl)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid block declaration: %1").arg(decl);
-        return UiStyle::Invalid;
+        return ItemFormatType::Invalid;
     }
     QString mainItemType = rx.cap(1);
     QString properties = rx.cap(2);
 
     }
     QString mainItemType = rx.cap(1);
     QString properties = rx.cap(2);
 
-    quint32 fmtType = 0;
+    ItemFormatType fmtType{ItemFormatType::None};
 
     // Next up: properties
     QString type, state;
     if (!properties.isEmpty()) {
         QHash<QString, QString> props;
 
     // Next up: properties
     QString type, state;
     if (!properties.isEmpty()) {
         QHash<QString, QString> props;
-        QRegExp propRx("\\s*([\\w\\-]+)\\s*=\\s*\"([\\w\\-]+)\"\\s*");
+        static const QRegExp propRx("\\s*([\\w\\-]+)\\s*=\\s*\"([\\w\\-]+)\"\\s*");
         foreach(const QString &prop, properties.split(',', QString::SkipEmptyParts)) {
             if (!propRx.exactMatch(prop)) {
                 qWarning() << Q_FUNC_INFO << tr("Invalid proplist %1").arg(prop);
         foreach(const QString &prop, properties.split(',', QString::SkipEmptyParts)) {
             if (!propRx.exactMatch(prop)) {
                 qWarning() << Q_FUNC_INFO << tr("Invalid proplist %1").arg(prop);
-                return UiStyle::Invalid;
+                return ItemFormatType::Invalid;
             }
             props[propRx.cap(1)] = propRx.cap(2);
         }
             }
             props[propRx.cap(1)] = propRx.cap(2);
         }
@@ -374,46 +385,46 @@ quint32 QssParser::parseItemFormatType(const QString &decl)
     }
 
     if (mainItemType == "Chat") {
     }
 
     if (mainItemType == "Chat") {
-        fmtType |= UiStyle::BufferViewItem;
+        fmtType |= ItemFormatType::BufferViewItem;
         if (!type.isEmpty()) {
             if (type == "network")
         if (!type.isEmpty()) {
             if (type == "network")
-                fmtType |= UiStyle::NetworkItem;
+                fmtType |= ItemFormatType::NetworkItem;
             else if (type == "channel")
             else if (type == "channel")
-                fmtType |= UiStyle::ChannelBufferItem;
+                fmtType |= ItemFormatType::ChannelBufferItem;
             else if (type == "query")
             else if (type == "query")
-                fmtType |= UiStyle::QueryBufferItem;
+                fmtType |= ItemFormatType::QueryBufferItem;
             else {
                 qWarning() << Q_FUNC_INFO << tr("Invalid chatlist item type %1").arg(type);
             else {
                 qWarning() << Q_FUNC_INFO << tr("Invalid chatlist item type %1").arg(type);
-                return UiStyle::Invalid;
+                return ItemFormatType::Invalid;
             }
         }
         if (!state.isEmpty()) {
             if (state == "inactive")
             }
         }
         if (!state.isEmpty()) {
             if (state == "inactive")
-                fmtType |= UiStyle::InactiveBuffer;
+                fmtType |= ItemFormatType::InactiveBuffer;
             else if (state == "channel-event")
             else if (state == "channel-event")
-                fmtType |= UiStyle::ActiveBuffer;
+                fmtType |= ItemFormatType::ActiveBuffer;
             else if (state == "unread-message")
             else if (state == "unread-message")
-                fmtType |= UiStyle::UnreadBuffer;
+                fmtType |= ItemFormatType::UnreadBuffer;
             else if (state == "highlighted")
             else if (state == "highlighted")
-                fmtType |= UiStyle::HighlightedBuffer;
+                fmtType |= ItemFormatType::HighlightedBuffer;
             else if (state == "away")
             else if (state == "away")
-                fmtType |= UiStyle::UserAway;
+                fmtType |= ItemFormatType::UserAway;
             else {
                 qWarning() << Q_FUNC_INFO << tr("Invalid chatlist state %1").arg(state);
             else {
                 qWarning() << Q_FUNC_INFO << tr("Invalid chatlist state %1").arg(state);
-                return UiStyle::Invalid;
+                return ItemFormatType::Invalid;
             }
         }
     }
     else { // NickList
             }
         }
     }
     else { // NickList
-        fmtType |= UiStyle::NickViewItem;
+        fmtType |= ItemFormatType::NickViewItem;
         if (!type.isEmpty()) {
             if (type == "user") {
         if (!type.isEmpty()) {
             if (type == "user") {
-                fmtType |= UiStyle::IrcUserItem;
+                fmtType |= ItemFormatType::IrcUserItem;
                 if (state == "away")
                 if (state == "away")
-                    fmtType |= UiStyle::UserAway;
+                    fmtType |= ItemFormatType::UserAway;
             }
             else if (type == "category")
             }
             else if (type == "category")
-                fmtType |= UiStyle::UserCategoryItem;
+                fmtType |= ItemFormatType::UserCategoryItem;
         }
     }
     return fmtType;
         }
     }
     return fmtType;
@@ -495,7 +506,7 @@ QBrush QssParser::parseBrush(const QString &str, bool *ok)
         //   [0-9]     Match any digit from 0-9
         // Note that '\' must be escaped as '\\'
         // Helpful interactive website for debugging and explaining:  https://regex101.com/
         //   [0-9]     Match any digit from 0-9
         // Note that '\' must be escaped as '\\'
         // Helpful interactive website for debugging and explaining:  https://regex101.com/
-        QRegExp rx("palette\\s*\\(\\s*([a-z-0-9]+)\\s*\\)");
+        static const QRegExp rx("palette\\s*\\(\\s*([a-z-0-9]+)\\s*\\)");
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid palette color role specification: %1").arg(str);
             return QBrush();
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid palette color role specification: %1").arg(str);
             return QBrush();
@@ -503,13 +514,13 @@ QBrush QssParser::parseBrush(const QString &str, bool *ok)
         if (_paletteColorRoles.contains(rx.cap(1)))
             return QBrush(_palette.brush(_paletteColorRoles.value(rx.cap(1))));
         if (_uiStyleColorRoles.contains(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))));
+            return QBrush(_uiStylePalette.at(static_cast<int>(_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")) {
         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*");
-        QRegExp rx(QString("qlineargradient\\s*\\(\\s*x1:%1,\\s*y1:%1,\\s*x2:%1,\\s*y2:%1,(.+)\\)").arg(rxFloat));
+        static const QString rxFloat("\\s*(-?\\s*[0-9]*\\.?[0-9]+)\\s*");
+        static const QRegExp rx(QString("qlineargradient\\s*\\(\\s*x1:%1,\\s*y1:%1,\\s*x2:%1,\\s*y2:%1,(.+)\\)").arg(rxFloat));
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid gradient declaration: %1").arg(str);
             return QBrush();
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid gradient declaration: %1").arg(str);
             return QBrush();
@@ -531,8 +542,8 @@ QBrush QssParser::parseBrush(const QString &str, bool *ok)
         return QBrush(gradient);
     }
     else if (str.startsWith("qconicalgradient")) {
         return QBrush(gradient);
     }
     else if (str.startsWith("qconicalgradient")) {
-        static QString rxFloat("\\s*(-?\\s*[0-9]*\\.?[0-9]+)\\s*");
-        QRegExp rx(QString("qconicalgradient\\s*\\(\\s*cx:%1,\\s*cy:%1,\\s*angle:%1,(.+)\\)").arg(rxFloat));
+        static const QString rxFloat("\\s*(-?\\s*[0-9]*\\.?[0-9]+)\\s*");
+        static const QRegExp rx(QString("qconicalgradient\\s*\\(\\s*cx:%1,\\s*cy:%1,\\s*angle:%1,(.+)\\)").arg(rxFloat));
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid gradient declaration: %1").arg(str);
             return QBrush();
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid gradient declaration: %1").arg(str);
             return QBrush();
@@ -553,8 +564,8 @@ QBrush QssParser::parseBrush(const QString &str, bool *ok)
         return QBrush(gradient);
     }
     else if (str.startsWith("qradialgradient")) {
         return QBrush(gradient);
     }
     else if (str.startsWith("qradialgradient")) {
-        static QString rxFloat("\\s*(-?\\s*[0-9]*\\.?[0-9]+)\\s*");
-        QRegExp rx(QString("qradialgradient\\s*\\(\\s*cx:%1,\\s*cy:%1,\\s*radius:%1,\\s*fx:%1,\\s*fy:%1,(.+)\\)").arg(rxFloat));
+        static const QString rxFloat("\\s*(-?\\s*[0-9]*\\.?[0-9]+)\\s*");
+        static const QRegExp rx(QString("qradialgradient\\s*\\(\\s*cx:%1,\\s*cy:%1,\\s*radius:%1,\\s*fx:%1,\\s*fy:%1,(.+)\\)").arg(rxFloat));
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid gradient declaration: %1").arg(str);
             return QBrush();
         if (!rx.exactMatch(str)) {
             qWarning() << Q_FUNC_INFO << tr("Invalid gradient declaration: %1").arg(str);
             return QBrush();
@@ -610,7 +621,7 @@ QColor QssParser::parseColor(const QString &str)
         }
     }
     else {
         }
     }
     else {
-        QRegExp rx("#?[0-9A-Fa-z]+");
+        static const QRegExp rx("#?[0-9A-Fa-z]+");
         if (rx.exactMatch(str))
             return QColor(str);
     }
         if (rx.exactMatch(str))
             return QColor(str);
     }
@@ -622,7 +633,7 @@ QColor QssParser::parseColor(const QString &str)
 QssParser::ColorTuple QssParser::parseColorTuple(const QString &str)
 {
     ColorTuple result;
 QssParser::ColorTuple QssParser::parseColorTuple(const QString &str)
 {
     ColorTuple result;
-    QRegExp rx("\\(((\\s*[0-9]{1,3}%?\\s*)(,\\s*[0-9]{1,3}%?\\s*)*)\\)");
+    static const QRegExp rx("\\(((\\s*[0-9]{1,3}%?\\s*)(,\\s*[0-9]{1,3}%?\\s*)*)\\)");
     if (!rx.exactMatch(str.trimmed())) {
         return ColorTuple();
     }
     if (!rx.exactMatch(str.trimmed())) {
         return ColorTuple();
     }
@@ -651,8 +662,8 @@ QGradientStops QssParser::parseGradientStops(const QString &str_)
 {
     QString str = str_;
     QGradientStops result;
 {
     QString str = str_;
     QGradientStops result;
-    static QString rxFloat("(0?\\.[0-9]+|[01])"); // values between 0 and 1
-    QRegExp rx(QString("\\s*,?\\s*stop:\\s*(%1)\\s+([^:]+)(,\\s*stop:|$)").arg(rxFloat));
+    static const QString rxFloat("(0?\\.[0-9]+|[01])"); // values between 0 and 1
+    static const QRegExp rx(QString("\\s*,?\\s*stop:\\s*(%1)\\s+([^:]+)(,\\s*stop:|$)").arg(rxFloat));
     int idx;
     while ((idx = rx.indexIn(str)) == 0) {
         qreal x = rx.cap(1).toDouble();
     int idx;
     while ((idx = rx.indexIn(str)) == 0) {
         qreal x = rx.cap(1).toDouble();
@@ -673,7 +684,7 @@ QGradientStops QssParser::parseGradientStops(const QString &str_)
 
 void QssParser::parseFont(const QString &value, QTextCharFormat *format)
 {
 
 void QssParser::parseFont(const QString &value, QTextCharFormat *format)
 {
-    QRegExp rx("((?:(?:normal|italic|oblique|underline|bold|100|200|300|400|500|600|700|800|900) ){0,2}) ?(\\d+)(pt|px)? \"(.*)\"");
+    static const 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;
     if (!rx.exactMatch(value)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid font specification: %1").arg(value);
         return;
@@ -741,7 +752,7 @@ void QssParser::parseFontWeight(const QString &value, QTextCharFormat *format)
 
 void QssParser::parseFontSize(const QString &value, QTextCharFormat *format)
 {
 
 void QssParser::parseFontSize(const QString &value, QTextCharFormat *format)
 {
-    QRegExp rx("(\\d+)(pt|px)");
+    static const QRegExp rx("(\\d+)(pt|px)");
     if (!rx.exactMatch(value)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid font size specification: %1").arg(value);
         return;
     if (!rx.exactMatch(value)) {
         qWarning() << Q_FUNC_INFO << tr("Invalid font size specification: %1").arg(value);
         return;
index 228b024..1370c10 100644 (file)
@@ -18,8 +18,9 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
-#ifndef QSSPARSER_H_
-#define QSSPARSER_H_
+#pragma once
+
+#include <utility>
 
 #include "uistyle.h"
 
 
 #include "uistyle.h"
 
@@ -35,7 +36,7 @@ public:
     inline QPalette palette() const { return _palette; }
     inline QVector<QBrush> uiStylePalette() const { return _uiStylePalette; }
     inline const QHash<quint64, QTextCharFormat> &formats() const { return _formats; }
     inline QPalette palette() const { return _palette; }
     inline QVector<QBrush> uiStylePalette() const { return _uiStylePalette; }
     inline const QHash<quint64, QTextCharFormat> &formats() const { return _formats; }
-    inline const QHash<quint32, QTextCharFormat> &listItemFormats() const { return _listItemFormats; }
+    inline const QHash<UiStyle::ItemFormatType, QTextCharFormat> &listItemFormats() const { return _listItemFormats; }
 
 protected:
     typedef QList<qreal> ColorTuple;
 
 protected:
     typedef QList<qreal> ColorTuple;
@@ -44,8 +45,8 @@ protected:
     void parsePaletteBlock(const QString &decl, const QString &contents);
     void parseListItemBlock(const QString &decl, const QString &contents);
 
     void parsePaletteBlock(const QString &decl, const QString &contents);
     void parseListItemBlock(const QString &decl, const QString &contents);
 
-    quint64 parseFormatType(const QString &decl);
-    quint32 parseItemFormatType(const QString &decl);
+    std::pair<UiStyle::FormatType, UiStyle::MessageLabel> parseFormatType(const QString &decl);
+    UiStyle::ItemFormatType parseItemFormatType(const QString &decl);
 
     QTextCharFormat parseFormat(const QString &qss);
 
 
     QTextCharFormat parseFormat(const QString &qss);
 
@@ -69,8 +70,5 @@ private:
     QPalette _palette;
     QVector<QBrush> _uiStylePalette;
     QHash<quint64, QTextCharFormat> _formats;
     QPalette _palette;
     QVector<QBrush> _uiStylePalette;
     QHash<quint64, QTextCharFormat> _formats;
-    QHash<quint32, QTextCharFormat> _listItemFormats;
+    QHash<UiStyle::ItemFormatType, QTextCharFormat> _listItemFormats;
 };
 };
-
-
-#endif
index dc13660..059ab69 100644 (file)
@@ -122,8 +122,8 @@ void StyledLabel::setText(const QString &text)
 {
     UiStyle *style = GraphicalUi::uiStyle();
 
 {
     UiStyle *style = GraphicalUi::uiStyle();
 
-    UiStyle::StyledString sstr = style->styleString(style->mircToInternal(text), UiStyle::PlainMsg);
-    QList<QTextLayout::FormatRange> layoutList = style->toTextLayoutList(sstr.formatList, sstr.plainText.length(), 0);
+    UiStyle::StyledString sstr = style->styleString(style->mircToInternal(text), UiStyle::FormatType::PlainMsg);
+    QList<QTextLayout::FormatRange> layoutList = style->toTextLayoutList(sstr.formatList, sstr.plainText.length(), UiStyle::MessageLabel::None);
 
     // Use default font rather than the style's
     QTextLayout::FormatRange fmtRange;
 
     // Use default font rather than the style's
     QTextLayout::FormatRange fmtRange;
index 49d3fcb..9da5987 100644 (file)
@@ -39,19 +39,19 @@ UiStyleSettings::UiStyleSettings(const QString &subGroup) : UiSettings(QString("
 
 void UiStyleSettings::setCustomFormat(UiStyle::FormatType ftype, QTextCharFormat format)
 {
 
 void UiStyleSettings::setCustomFormat(UiStyle::FormatType ftype, QTextCharFormat format)
 {
-    setLocalValue(QString("Format/%1").arg(ftype), format);
+    setLocalValue(QString("Format/%1").arg(static_cast<quint32>(ftype)), format);
 }
 
 
 QTextCharFormat UiStyleSettings::customFormat(UiStyle::FormatType ftype)
 {
 }
 
 
 QTextCharFormat UiStyleSettings::customFormat(UiStyle::FormatType ftype)
 {
-    return localValue(QString("Format/%1").arg(ftype), QTextFormat()).value<QTextFormat>().toCharFormat();
+    return localValue(QString("Format/%1").arg(static_cast<quint32>(ftype)), QTextFormat()).value<QTextFormat>().toCharFormat();
 }
 
 
 void UiStyleSettings::removeCustomFormat(UiStyle::FormatType ftype)
 {
 }
 
 
 void UiStyleSettings::removeCustomFormat(UiStyle::FormatType ftype)
 {
-    removeLocalKey(QString("Format/%1").arg(ftype));
+    removeLocalKey(QString("Format/%1").arg(static_cast<quint32>(ftype)));
 }
 
 
 }
 
 
index 3b9e079..fc9ccb1 100644 (file)
@@ -18,6 +18,8 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
+#include <vector>
+
 #include <QApplication>
 #include <QIcon>
 
 #include <QApplication>
 #include <QIcon>
 
@@ -55,20 +57,20 @@ UiStyle::UiStyle(QObject *parent)
         Q_ASSERT(QVariant::nameToType("UiStyle::FormatList") != QVariant::Invalid);
     }
 
         Q_ASSERT(QVariant::nameToType("UiStyle::FormatList") != QVariant::Invalid);
     }
 
-    _uiStylePalette = QVector<QBrush>(NumRoles, QBrush());
+    _uiStylePalette = QVector<QBrush>(static_cast<int>(ColorRole::NumRoles), QBrush());
 
     // Now initialize the mapping between FormatCodes and FormatTypes...
 
     // Now initialize the mapping between FormatCodes and FormatTypes...
-    _formatCodes["%O"] = Base;
-    _formatCodes["%B"] = Bold;
-    _formatCodes["%S"] = Italic;
-    _formatCodes["%U"] = Underline;
-    _formatCodes["%R"] = Reverse;
-
-    _formatCodes["%DN"] = Nick;
-    _formatCodes["%DH"] = Hostmask;
-    _formatCodes["%DC"] = ChannelName;
-    _formatCodes["%DM"] = ModeFlags;
-    _formatCodes["%DU"] = Url;
+    _formatCodes["%O"] = FormatType::Base;
+    _formatCodes["%B"] = FormatType::Bold;
+    _formatCodes["%S"] = FormatType::Italic;
+    _formatCodes["%U"] = FormatType::Underline;
+    _formatCodes["%R"] = FormatType::Reverse;
+
+    _formatCodes["%DN"] = FormatType::Nick;
+    _formatCodes["%DH"] = FormatType::Hostmask;
+    _formatCodes["%DC"] = FormatType::ChannelName;
+    _formatCodes["%DM"] = FormatType::ModeFlags;
+    _formatCodes["%DU"] = FormatType::Url;
 
     // Initialize fallback defaults
     // NOTE: If you change this, update qtui/chatviewsettings.h, too.  More explanations available
 
     // Initialize fallback defaults
     // NOTE: If you change this, update qtui/chatviewsettings.h, too.  More explanations available
@@ -283,44 +285,44 @@ QVariant UiStyle::bufferViewItemData(const QModelIndex &index, int role) const
         }
     }
 
         }
     }
 
-    quint32 fmtType = BufferViewItem;
+    ItemFormatType fmtType = ItemFormatType::BufferViewItem;
     switch (type) {
     case BufferInfo::StatusBuffer:
     switch (type) {
     case BufferInfo::StatusBuffer:
-        fmtType |= NetworkItem;
+        fmtType |= ItemFormatType::NetworkItem;
         break;
     case BufferInfo::ChannelBuffer:
         break;
     case BufferInfo::ChannelBuffer:
-        fmtType |= ChannelBufferItem;
+        fmtType |= ItemFormatType::ChannelBufferItem;
         break;
     case BufferInfo::QueryBuffer:
         break;
     case BufferInfo::QueryBuffer:
-        fmtType |= QueryBufferItem;
+        fmtType |= ItemFormatType::QueryBufferItem;
         break;
     default:
         return QVariant();
     }
 
         break;
     default:
         return QVariant();
     }
 
-    QTextCharFormat fmt = _listItemFormats.value(BufferViewItem);
+    QTextCharFormat fmt = _listItemFormats.value(ItemFormatType::BufferViewItem);
     fmt.merge(_listItemFormats.value(fmtType));
 
     BufferInfo::ActivityLevel activity = (BufferInfo::ActivityLevel)index.data(NetworkModel::BufferActivityRole).toInt();
     if (activity & BufferInfo::Highlight) {
     fmt.merge(_listItemFormats.value(fmtType));
 
     BufferInfo::ActivityLevel activity = (BufferInfo::ActivityLevel)index.data(NetworkModel::BufferActivityRole).toInt();
     if (activity & BufferInfo::Highlight) {
-        fmt.merge(_listItemFormats.value(BufferViewItem | HighlightedBuffer));
-        fmt.merge(_listItemFormats.value(fmtType | HighlightedBuffer));
+        fmt.merge(_listItemFormats.value(ItemFormatType::BufferViewItem | ItemFormatType::HighlightedBuffer));
+        fmt.merge(_listItemFormats.value(fmtType | ItemFormatType::HighlightedBuffer));
     }
     else if (activity & BufferInfo::NewMessage) {
     }
     else if (activity & BufferInfo::NewMessage) {
-        fmt.merge(_listItemFormats.value(BufferViewItem | UnreadBuffer));
-        fmt.merge(_listItemFormats.value(fmtType | UnreadBuffer));
+        fmt.merge(_listItemFormats.value(ItemFormatType::BufferViewItem | ItemFormatType::UnreadBuffer));
+        fmt.merge(_listItemFormats.value(fmtType | ItemFormatType::UnreadBuffer));
     }
     else if (activity & BufferInfo::OtherActivity) {
     }
     else if (activity & BufferInfo::OtherActivity) {
-        fmt.merge(_listItemFormats.value(BufferViewItem | ActiveBuffer));
-        fmt.merge(_listItemFormats.value(fmtType | ActiveBuffer));
+        fmt.merge(_listItemFormats.value(ItemFormatType::BufferViewItem | ItemFormatType::ActiveBuffer));
+        fmt.merge(_listItemFormats.value(fmtType | ItemFormatType::ActiveBuffer));
     }
     else if (!isActive) {
     }
     else if (!isActive) {
-        fmt.merge(_listItemFormats.value(BufferViewItem | InactiveBuffer));
-        fmt.merge(_listItemFormats.value(fmtType | InactiveBuffer));
+        fmt.merge(_listItemFormats.value(ItemFormatType::BufferViewItem | ItemFormatType::InactiveBuffer));
+        fmt.merge(_listItemFormats.value(fmtType | ItemFormatType::InactiveBuffer));
     }
     else if (index.data(NetworkModel::UserAwayRole).toBool()) {
     }
     else if (index.data(NetworkModel::UserAwayRole).toBool()) {
-        fmt.merge(_listItemFormats.value(BufferViewItem | UserAway));
-        fmt.merge(_listItemFormats.value(fmtType | UserAway));
+        fmt.merge(_listItemFormats.value(ItemFormatType::BufferViewItem | ItemFormatType::UserAway));
+        fmt.merge(_listItemFormats.value(fmtType | ItemFormatType::UserAway));
     }
 
     return itemData(role, fmt);
     }
 
     return itemData(role, fmt);
@@ -355,18 +357,18 @@ QVariant UiStyle::nickViewItemData(const QModelIndex &index, int role) const
         }
     }
 
         }
     }
 
-    QTextCharFormat fmt = _listItemFormats.value(NickViewItem);
+    QTextCharFormat fmt = _listItemFormats.value(ItemFormatType::NickViewItem);
 
     switch (type) {
     case NetworkModel::IrcUserItemType:
 
     switch (type) {
     case NetworkModel::IrcUserItemType:
-        fmt.merge(_listItemFormats.value(NickViewItem | IrcUserItem));
+        fmt.merge(_listItemFormats.value(ItemFormatType::NickViewItem | ItemFormatType::IrcUserItem));
         if (!index.data(NetworkModel::ItemActiveRole).toBool()) {
         if (!index.data(NetworkModel::ItemActiveRole).toBool()) {
-            fmt.merge(_listItemFormats.value(NickViewItem | UserAway));
-            fmt.merge(_listItemFormats.value(NickViewItem | IrcUserItem | UserAway));
+            fmt.merge(_listItemFormats.value(ItemFormatType::NickViewItem | ItemFormatType::UserAway));
+            fmt.merge(_listItemFormats.value(ItemFormatType::NickViewItem | ItemFormatType::IrcUserItem | ItemFormatType::UserAway));
         }
         break;
     case NetworkModel::UserCategoryItemType:
         }
         break;
     case NetworkModel::UserCategoryItemType:
-        fmt.merge(_listItemFormats.value(NickViewItem | UserCategoryItem));
+        fmt.merge(_listItemFormats.value(ItemFormatType::NickViewItem | ItemFormatType::UserCategoryItem));
         break;
     default:
         return QVariant();
         break;
     default:
         return QVariant();
@@ -399,22 +401,22 @@ QTextCharFormat UiStyle::format(quint64 key) const
 }
 
 
 }
 
 
-QTextCharFormat UiStyle::cachedFormat(quint32 formatType, quint32 messageLabel) const
+QTextCharFormat UiStyle::cachedFormat(FormatType formatType, MessageLabel messageLabel) const
 {
 {
-    return _formatCache.value(formatType | ((quint64)messageLabel << 32), QTextCharFormat());
+    return _formatCache.value(formatType | messageLabel, QTextCharFormat());
 }
 
 
 }
 
 
-void UiStyle::setCachedFormat(const QTextCharFormat &format, quint32 formatType, quint32 messageLabel) const
+void UiStyle::setCachedFormat(const QTextCharFormat &format, FormatType formatType, MessageLabel messageLabel) const
 {
 {
-    _formatCache[formatType | ((quint64)messageLabel << 32)] = format;
+    _formatCache[formatType | messageLabel] = format;
 }
 
 
 }
 
 
-QFontMetricsF *UiStyle::fontMetrics(quint32 ftype, quint32 label) const
+QFontMetricsF *UiStyle::fontMetrics(FormatType ftype, MessageLabel label) const
 {
     // QFontMetricsF is not assignable, so we need to store pointers :/
 {
     // QFontMetricsF is not assignable, so we need to store pointers :/
-    quint64 key = ftype | ((quint64)label << 32);
+    quint64 key = ftype | label;
 
     if (_metricsCache.contains(key))
         return _metricsCache.value(key);
 
     if (_metricsCache.contains(key))
         return _metricsCache.value(key);
@@ -427,39 +429,37 @@ QFontMetricsF *UiStyle::fontMetrics(quint32 ftype, quint32 label) const
 
 // 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!
 
 // 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_) const
+QTextCharFormat UiStyle::format(FormatType ftype, MessageLabel label) const
 {
 {
-    if (ftype == Invalid)
-        return QTextCharFormat();
-
-    quint64 label = (quint64)label_ << 32;
+    if (ftype == FormatType::Invalid)
+        return {};
 
     // check if we have exactly this format readily cached already
 
     // check if we have exactly this format readily cached already
-    QTextCharFormat fmt = cachedFormat(ftype, label_);
+    QTextCharFormat fmt = cachedFormat(ftype, label);
     if (fmt.properties().count())
         return fmt;
 
     if (fmt.properties().count())
         return fmt;
 
-    mergeFormat(fmt, ftype, label & Q_UINT64_C(0xffff000000000000));
+    mergeFormat(fmt, ftype, label & 0xffff0000);  // keep nickhash in label
 
 
-    for (quint64 mask = Q_UINT64_C(0x0000000100000000); mask <= (quint64)Selected << 32; mask <<= 1) {
-        if (label & mask)
-            mergeFormat(fmt, ftype, mask | Q_UINT64_C(0xffff000000000000));
+    for (quint32 mask = 0x00000001; mask <= static_cast<quint32>(MessageLabel::Selected); mask <<= 1) {
+        if (static_cast<quint32>(label) & mask)
+            mergeFormat(fmt, ftype, label & (mask | 0xffff0000));
     }
 
     }
 
-    setCachedFormat(fmt, ftype, label_);
+    setCachedFormat(fmt, ftype, label);
     return fmt;
 }
 
 
     return fmt;
 }
 
 
-void UiStyle::mergeFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) const
+void UiStyle::mergeFormat(QTextCharFormat &fmt, FormatType ftype, MessageLabel 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"
     //       or "foreground 01 and background 03"
 {
     mergeSubElementFormat(fmt, ftype & 0x00ff, label);
 
     // TODO: allow combinations for mirc formats and colors (each), e.g. setting a special format for "bold and italic"
     //       or "foreground 01 and background 03"
-    if ((ftype & 0xfff00)) { // element format
+    if ((ftype & 0xfff00) != FormatType::Base) { // element format
         for (quint32 mask = 0x00100; mask <= 0x40000; mask <<= 1) {
         for (quint32 mask = 0x00100; mask <= 0x40000; mask <<= 1) {
-            if (ftype & mask) {
+            if ((ftype & mask) != FormatType::Base) {
                 mergeSubElementFormat(fmt, ftype & (mask | 0xff), label);
             }
         }
                 mergeSubElementFormat(fmt, ftype & (mask | 0xff), label);
             }
         }
@@ -468,28 +468,28 @@ void UiStyle::mergeFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) co
     // Now we handle color codes
     // We assume that those can't be combined with subelement and message types.
     if (_allowMircColors) {
     // Now we handle color codes
     // We assume that those can't be combined with subelement and message types.
     if (_allowMircColors) {
-        if (ftype & 0x00400000)
+        if ((ftype & 0x00400000) != FormatType::Base)
             mergeSubElementFormat(fmt, ftype & 0x0f400000, label);  // foreground
             mergeSubElementFormat(fmt, ftype & 0x0f400000, label);  // foreground
-        if (ftype & 0x00800000)
+        if ((ftype & 0x00800000) != FormatType::Base)
             mergeSubElementFormat(fmt, ftype & 0xf0800000, label);  // background
             mergeSubElementFormat(fmt, ftype & 0xf0800000, label);  // background
-        if ((ftype & 0x00c00000) == 0x00c00000)
+        if ((ftype & 0x00c00000) == static_cast<FormatType>(0x00c00000))
             mergeSubElementFormat(fmt, ftype & 0xffc00000, label);  // combination
     }
 
     // URL
             mergeSubElementFormat(fmt, ftype & 0xffc00000, label);  // combination
     }
 
     // URL
-    if (ftype & Url)
-        mergeSubElementFormat(fmt, ftype & (Url | 0x000000ff), label);
+    if ((ftype & FormatType::Url) != FormatType::Base)
+        mergeSubElementFormat(fmt, ftype & (FormatType::Url | static_cast<FormatType>(0x000000ff)), label);
 }
 
 
 // Merge a subelement format into an existing message format
 }
 
 
 // Merge a subelement format into an existing message format
-void UiStyle::mergeSubElementFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) const
+void UiStyle::mergeSubElementFormat(QTextCharFormat &fmt, FormatType ftype, MessageLabel label) const
 {
     quint64 key = ftype | label;
 {
     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
-    fmt.merge(format(key & Q_UINT64_C(0xffffffffffffff00))); // label + subelement + nickhash
-    fmt.merge(format(key & Q_UINT64_C(0xffffffffffffffff))); // label + subelement + nickhash + msgtype
+    fmt.merge(format(key & 0x0000ffffffffff00ull)); // label + subelement
+    fmt.merge(format(key & 0x0000ffffffffffffull)); // label + subelement + msgtype
+    fmt.merge(format(key & 0xffffffffffffff00ull)); // label + subelement + nickhash
+    fmt.merge(format(key & 0xffffffffffffffffull)); // label + subelement + nickhash + msgtype
 }
 
 
 }
 
 
@@ -497,52 +497,53 @@ UiStyle::FormatType UiStyle::formatType(Message::Type msgType)
 {
     switch (msgType) {
     case Message::Plain:
 {
     switch (msgType) {
     case Message::Plain:
-        return PlainMsg;
+        return FormatType::PlainMsg;
     case Message::Notice:
     case Message::Notice:
-        return NoticeMsg;
+        return FormatType::NoticeMsg;
     case Message::Action:
     case Message::Action:
-        return ActionMsg;
+        return FormatType::ActionMsg;
     case Message::Nick:
     case Message::Nick:
-        return NickMsg;
+        return FormatType::NickMsg;
     case Message::Mode:
     case Message::Mode:
-        return ModeMsg;
+        return FormatType::ModeMsg;
     case Message::Join:
     case Message::Join:
-        return JoinMsg;
+        return FormatType::JoinMsg;
     case Message::Part:
     case Message::Part:
-        return PartMsg;
+        return FormatType::PartMsg;
     case Message::Quit:
     case Message::Quit:
-        return QuitMsg;
+        return FormatType::QuitMsg;
     case Message::Kick:
     case Message::Kick:
-        return KickMsg;
+        return FormatType::KickMsg;
     case Message::Kill:
     case Message::Kill:
-        return KillMsg;
+        return FormatType::KillMsg;
     case Message::Server:
     case Message::Server:
-        return ServerMsg;
+        return FormatType::ServerMsg;
     case Message::Info:
     case Message::Info:
-        return InfoMsg;
+        return FormatType::InfoMsg;
     case Message::Error:
     case Message::Error:
-        return ErrorMsg;
+        return FormatType::ErrorMsg;
     case Message::DayChange:
     case Message::DayChange:
-        return DayChangeMsg;
+        return FormatType::DayChangeMsg;
     case Message::Topic:
     case Message::Topic:
-        return TopicMsg;
+        return FormatType::TopicMsg;
     case Message::NetsplitJoin:
     case Message::NetsplitJoin:
-        return NetsplitJoinMsg;
+        return FormatType::NetsplitJoinMsg;
     case Message::NetsplitQuit:
     case Message::NetsplitQuit:
-        return NetsplitQuitMsg;
+        return FormatType::NetsplitQuitMsg;
     case Message::Invite:
     case Message::Invite:
-        return InviteMsg;
+        return FormatType::InviteMsg;
     }
     //Q_ASSERT(false); // we need to handle all message types
     qWarning() << Q_FUNC_INFO << "Unknown message type:" << msgType;
     }
     //Q_ASSERT(false); // we need to handle all message types
     qWarning() << Q_FUNC_INFO << "Unknown message type:" << msgType;
-    return ErrorMsg;
+    return FormatType::ErrorMsg;
 }
 
 
 UiStyle::FormatType UiStyle::formatType(const QString &code)
 {
 }
 
 
 UiStyle::FormatType UiStyle::formatType(const QString &code)
 {
-    if (_formatCodes.contains(code)) return _formatCodes.value(code);
-    return Invalid;
+    if (_formatCodes.contains(code))
+        return _formatCodes.value(code);
+    return FormatType::Invalid;
 }
 
 
 }
 
 
@@ -552,29 +553,31 @@ QString UiStyle::formatCode(FormatType ftype)
 }
 
 
 }
 
 
-QList<QTextLayout::FormatRange> UiStyle::toTextLayoutList(const FormatList &formatList, int textLength, quint32 messageLabel) const
+QList<QTextLayout::FormatRange> UiStyle::toTextLayoutList(const FormatList &formatList, int textLength, MessageLabel messageLabel) const
 {
     QList<QTextLayout::FormatRange> formatRanges;
     QTextLayout::FormatRange range;
 {
     QList<QTextLayout::FormatRange> formatRanges;
     QTextLayout::FormatRange range;
-    int i = 0;
-    for (i = 0; i < formatList.count(); i++) {
-        range.format = format(formatList.at(i).second, messageLabel);
+    size_t i = 0;
+    for (i = 0; i < formatList.size(); i++) {
+        range.format = format(formatList.at(i).second.type, messageLabel);
         range.start = formatList.at(i).first;
         range.start = formatList.at(i).first;
-        if (i > 0) formatRanges.last().length = range.start - formatRanges.last().start;
+        if (i > 0)
+            formatRanges.last().length = range.start - formatRanges.last().start;
         formatRanges.append(range);
     }
         formatRanges.append(range);
     }
-    if (i > 0) formatRanges.last().length = textLength - formatRanges.last().start;
+    if (i > 0)
+        formatRanges.last().length = textLength - formatRanges.last().start;
     return formatRanges;
 }
 
 
 // This method expects a well-formatted string, there is no error checking!
 // Since we create those ourselves, we should be pretty safe that nobody does something crappy here.
     return formatRanges;
 }
 
 
 // This method expects a well-formatted string, there is no error checking!
 // Since we create those ourselves, we should be pretty safe that nobody does something crappy here.
-UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat)
+UiStyle::StyledString UiStyle::styleString(const QString &s_, FormatType baseFormat)
 {
     QString s = s_;
     StyledString result;
 {
     QString s = s_;
     StyledString result;
-    result.formatList.append(qMakePair((quint16)0, baseFormat));
+    result.formatList.emplace_back(std::make_pair(quint16{0}, Format{baseFormat}));
 
     if (s.length() > 65535) {
         // We use quint16 for indexes
 
     if (s.length() > 65535) {
         // We use quint16 for indexes
@@ -583,7 +586,8 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat
         return result;
     }
 
         return result;
     }
 
-    quint32 curfmt = baseFormat;
+    FormatType curfmt = baseFormat;
+
     int pos = 0; quint16 length = 0;
     for (;;) {
         pos = s.indexOf('%', pos);
     int pos = 0; quint16 length = 0;
     for (;;) {
         pos = s.indexOf('%', pos);
@@ -626,7 +630,7 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat
             QString code = QString("%") + s[pos+1];
             if (s[pos+1] == 'D') code += s[pos+2];
             FormatType ftype = formatType(code);
             QString code = QString("%") + s[pos+1];
             if (s[pos+1] == 'D') code += s[pos+2];
             FormatType ftype = formatType(code);
-            if (ftype == Invalid) {
+            if (ftype == FormatType::Invalid) {
                 pos++;
                 qWarning() << (QString("Invalid format code in string: %1").arg(s));
                 continue;
                 pos++;
                 qWarning() << (QString("Invalid format code in string: %1").arg(s));
                 continue;
@@ -635,10 +639,10 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat
             length = code.length();
         }
         s.remove(pos, length);
             length = code.length();
         }
         s.remove(pos, length);
-        if (pos == result.formatList.last().first)
-            result.formatList.last().second = curfmt;
+        if (pos == result.formatList.back().first)
+            result.formatList.back().second.type = curfmt;
         else
         else
-            result.formatList.append(qMakePair((quint16)pos, curfmt));
+            result.formatList.emplace_back(std::make_pair(pos, Format{curfmt}));
     }
     result.plainText = s;
     return result;
     }
     result.plainText = s;
     return result;
@@ -928,44 +932,43 @@ QString UiStyle::StyledMessage::decoratedSender() const
             return QString("<%1%2>").arg(_senderPrefixes, plainSender());
         else
             return QString("%1%2").arg(_senderPrefixes, plainSender());
             return QString("<%1%2>").arg(_senderPrefixes, plainSender());
         else
             return QString("%1%2").arg(_senderPrefixes, plainSender());
-        break;
     case Message::Notice:
     case Message::Notice:
-        return QString("[%1%2]").arg(_senderPrefixes, plainSender()); break;
+        return QString("[%1%2]").arg(_senderPrefixes, plainSender());
     case Message::Action:
     case Message::Action:
-        return "-*-"; break;
+        return "-*-";
     case Message::Nick:
     case Message::Nick:
-        return "<->"; break;
+        return "<->";
     case Message::Mode:
     case Message::Mode:
-        return "***"; break;
+        return "***";
     case Message::Join:
     case Message::Join:
-        return "-->"; break;
+        return "-->";
     case Message::Part:
     case Message::Part:
-        return "<--"; break;
+        return "<--";
     case Message::Quit:
     case Message::Quit:
-        return "<--"; break;
+        return "<--";
     case Message::Kick:
     case Message::Kick:
-        return "<-*"; break;
+        return "<-*";
     case Message::Kill:
     case Message::Kill:
-        return "<-x"; break;
+        return "<-x";
     case Message::Server:
     case Message::Server:
-        return "*"; break;
+        return "*";
     case Message::Info:
     case Message::Info:
-        return "*"; break;
+        return "*";
     case Message::Error:
     case Message::Error:
-        return "*"; break;
+        return "*";
     case Message::DayChange:
     case Message::DayChange:
-        return "-"; break;
+        return "-";
     case Message::Topic:
     case Message::Topic:
-        return "*"; break;
+        return "*";
     case Message::NetsplitJoin:
     case Message::NetsplitJoin:
-        return "=>"; break;
+        return "=>";
     case Message::NetsplitQuit:
     case Message::NetsplitQuit:
-        return "<="; break;
+        return "<=";
     case Message::Invite:
     case Message::Invite:
-        return "->"; break;
-    default:
-        return QString("%1%2").arg(_senderPrefixes, plainSender());
+        return "->";
     }
     }
+
+    return QString("%1%2").arg(_senderPrefixes, plainSender());
 }
 
 
 }
 
 
@@ -999,15 +1002,132 @@ quint8 UiStyle::StyledMessage::senderHash() const
     return (_senderHash = (hash & 0xf) + 1);
 }
 
     return (_senderHash = (hash & 0xf) + 1);
 }
 
+/***********************************************************************************/
+
+#if QT_VERSION < 0x050000
+uint qHash(UiStyle::ItemFormatType key)
+{
+    return qHash(static_cast<quint32>(key));
+}
+
+#else
+
+uint qHash(UiStyle::ItemFormatType key, uint seed)
+{
+    return qHash(static_cast<quint32>(key), seed);
+}
+#endif
+
+UiStyle::FormatType operator|(UiStyle::FormatType lhs, UiStyle::FormatType rhs)
+{
+    return static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) | static_cast<quint32>(rhs));
+}
+
+UiStyle::FormatType& operator|=(UiStyle::FormatType& lhs, UiStyle::FormatType rhs)
+{
+    lhs = static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) | static_cast<quint32>(rhs));
+    return lhs;
+}
+
+
+UiStyle::FormatType operator|(UiStyle::FormatType lhs, quint32 rhs)
+{
+    return static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) | rhs);
+}
+
+
+UiStyle::FormatType& operator|=(UiStyle::FormatType &lhs, quint32 rhs)
+{
+    lhs = static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) | rhs);
+    return lhs;
+}
+
+
+UiStyle::FormatType operator&(UiStyle::FormatType lhs, UiStyle::FormatType rhs)
+{
+    return static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) & static_cast<quint32>(rhs));
+}
+
+
+UiStyle::FormatType& operator&=(UiStyle::FormatType &lhs, UiStyle::FormatType rhs)
+{
+    lhs = static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) & static_cast<quint32>(rhs));
+    return lhs;
+}
+
+
+UiStyle::FormatType operator&(UiStyle::FormatType lhs, quint32 rhs)
+{
+    return static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) & rhs);
+}
+
+
+UiStyle::FormatType& operator&=(UiStyle::FormatType &lhs, quint32 rhs)
+{
+    lhs = static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) & rhs);
+    return lhs;
+}
+
+
+UiStyle::FormatType& operator^=(UiStyle::FormatType &lhs, UiStyle::FormatType rhs)
+{
+    lhs = static_cast<UiStyle::FormatType>(static_cast<quint32>(lhs) ^ static_cast<quint32>(rhs));
+    return lhs;
+}
+
+
+UiStyle::MessageLabel operator|(UiStyle::MessageLabel lhs, UiStyle::MessageLabel rhs)
+{
+    return static_cast<UiStyle::MessageLabel>(static_cast<quint32>(lhs) | static_cast<quint32>(rhs));
+}
+
+
+UiStyle::MessageLabel& operator|=(UiStyle::MessageLabel &lhs, UiStyle::MessageLabel rhs)
+{
+    lhs = static_cast<UiStyle::MessageLabel>(static_cast<quint32>(lhs) | static_cast<quint32>(rhs));
+    return lhs;
+}
+
+
+UiStyle::MessageLabel operator&(UiStyle::MessageLabel lhs, quint32 rhs)
+{
+    return static_cast<UiStyle::MessageLabel>(static_cast<quint32>(lhs) & rhs);
+}
+
+
+UiStyle::MessageLabel& operator&=(UiStyle::MessageLabel &lhs, UiStyle::MessageLabel rhs)
+{
+    lhs = static_cast<UiStyle::MessageLabel>(static_cast<quint32>(lhs) & static_cast<quint32>(rhs));
+    return lhs;
+}
+
+
+quint64 operator|(UiStyle::FormatType lhs, UiStyle::MessageLabel rhs)
+{
+    return static_cast<quint64>(lhs) | (static_cast<quint64>(rhs) << 32ull);
+}
+
+
+UiStyle::ItemFormatType operator|(UiStyle::ItemFormatType lhs, UiStyle::ItemFormatType rhs)
+{
+    return static_cast<UiStyle::ItemFormatType>(static_cast<quint32>(lhs) | static_cast<quint32>(rhs));
+}
+
+
+UiStyle::ItemFormatType& operator|=(UiStyle::ItemFormatType &lhs, UiStyle::ItemFormatType rhs)
+{
+    lhs = static_cast<UiStyle::ItemFormatType>(static_cast<quint32>(lhs) | static_cast<quint32>(rhs));
+    return lhs;
+}
 
 /***********************************************************************************/
 
 QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList)
 {
 
 /***********************************************************************************/
 
 QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList)
 {
-    out << formatList.count();
+    out << static_cast<quint16>(formatList.size());
     UiStyle::FormatList::const_iterator it = formatList.begin();
     while (it != formatList.end()) {
     UiStyle::FormatList::const_iterator it = formatList.begin();
     while (it != formatList.end()) {
-        out << (*it).first << (*it).second;
+        out << it->first << static_cast<quint32>(it->second.type);
         ++it;
     }
     return out;
         ++it;
     }
     return out;
@@ -1021,7 +1141,7 @@ QDataStream &operator>>(QDataStream &in, UiStyle::FormatList &formatList)
     for (quint16 i = 0; i < cnt; i++) {
         quint16 pos; quint32 ftype;
         in >> pos >> ftype;
     for (quint16 i = 0; i < cnt; i++) {
         quint16 pos; quint32 ftype;
         in >> pos >> ftype;
-        formatList.append(qMakePair((quint16)pos, ftype));
+        formatList.emplace_back(std::make_pair(quint16{pos}, UiStyle::Format{static_cast<UiStyle::FormatType>(ftype)}));
     }
     return in;
 }
     }
     return in;
 }
index d565e5b..7d1a8bc 100644 (file)
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
-#ifndef UISTYLE_H_
-#define UISTYLE_H_
+#pragma once
+
+#include <utility>
+#include <vector>
 
 #include <QDataStream>
 #include <QFontMetricsF>
 
 #include <QDataStream>
 #include <QFontMetricsF>
@@ -43,8 +45,6 @@ public:
     UiStyle(QObject *parent = 0);
     virtual ~UiStyle();
 
     UiStyle(QObject *parent = 0);
     virtual ~UiStyle();
 
-    typedef QList<QPair<quint16, quint32> > FormatList;
-
     //! This enumerates the possible formats a text element may have. */
     /** These formats are ordered on increasing importance, in cases where a given property is specified
      *  by multiple active formats.
     //! This enumerates the possible formats a text element may have. */
     /** These formats are ordered on increasing importance, in cases where a given property is specified
      *  by multiple active formats.
@@ -52,7 +52,7 @@ public:
      *         methods in this class (in particular mergedFormat())!
      *         Also, we _do_ rely on certain properties of these values in styleString() and friends!
      */
      *         methods in this class (in particular mergedFormat())!
      *         Also, we _do_ rely on certain properties of these values in styleString() and friends!
      */
-    enum FormatType {
+    enum class FormatType : quint32 {
         Base            = 0x00000000,
         Invalid         = 0xffffffff,
 
         Base            = 0x00000000,
         Invalid         = 0xffffffff,
 
@@ -99,13 +99,16 @@ public:
                           // background: 0x.0800000
     };
 
                           // background: 0x.0800000
     };
 
-    enum MessageLabel {
+    enum class MessageLabel : quint32 {
+        None            = 0x00000000,
         OwnMsg          = 0x00000001,
         Highlight       = 0x00000002,
         Selected        = 0x00000004 // must be last!
     };
 
         OwnMsg          = 0x00000001,
         Highlight       = 0x00000002,
         Selected        = 0x00000004 // must be last!
     };
 
-    enum ItemFormatType {
+    enum class ItemFormatType : quint32 {
+        None              = 0x00000000,
+
         BufferViewItem    = 0x00000001,
         NickViewItem      = 0x00000002,
 
         BufferViewItem    = 0x00000001,
         NickViewItem      = 0x00000002,
 
@@ -119,10 +122,12 @@ public:
         ActiveBuffer      = 0x00002000,
         UnreadBuffer      = 0x00004000,
         HighlightedBuffer = 0x00008000,
         ActiveBuffer      = 0x00002000,
         UnreadBuffer      = 0x00004000,
         HighlightedBuffer = 0x00008000,
-        UserAway          = 0x00010000
+        UserAway          = 0x00010000,
+
+        Invalid           = 0xffffffff
     };
 
     };
 
-    enum ColorRole {
+    enum class ColorRole {
         MarkerLine,
         // Sender colors (16 + self)
         // These aren't used directly to avoid having storing all of the sender color options in the
         MarkerLine,
         // Sender colors (16 + self)
         // These aren't used directly to avoid having storing all of the sender color options in the
@@ -151,6 +156,12 @@ public:
         NumRoles // must be last!
     };
 
         NumRoles // must be last!
     };
 
+    struct Format {
+        FormatType type;
+    };
+
+    using FormatList = std::vector<std::pair<quint16, Format>>;
+
     struct StyledString {
         QString plainText;
         FormatList formatList; // starting pos, ftypes
     struct StyledString {
         QString plainText;
         FormatList formatList; // starting pos, ftypes
@@ -201,7 +212,7 @@ public:
     const QColor defaultSenderColorSelf = QColor(0, 0, 0);
 
     static FormatType formatType(Message::Type msgType);
     const QColor defaultSenderColorSelf = QColor(0, 0, 0);
 
     static FormatType formatType(Message::Type msgType);
-    static StyledString styleString(const QString &string, quint32 baseFormat = Base);
+    static StyledString styleString(const QString &string, FormatType baseFormat = FormatType::Base);
     static QString mircToInternal(const QString &);
 
     /**
     static QString mircToInternal(const QString &);
 
     /**
@@ -231,10 +242,10 @@ public:
      */
     static QString timestampFormatString();
 
      */
     static QString timestampFormatString();
 
-    QTextCharFormat format(quint32 formatType, quint32 messageLabel) const;
-    QFontMetricsF *fontMetrics(quint32 formatType, quint32 messageLabel) const;
+    QTextCharFormat format(FormatType formatType, MessageLabel messageLabel) const;
+    QFontMetricsF *fontMetrics(FormatType formatType, MessageLabel messageLabel) const;
 
 
-    QList<QTextLayout::FormatRange> toTextLayoutList(const FormatList &, int textLength, quint32 messageLabel) const;
+    QList<QTextLayout::FormatRange> toTextLayoutList(const FormatList &, int textLength, MessageLabel messageLabel) const;
 
     inline const QBrush &brush(ColorRole role) const { return _uiStylePalette.at((int)role); }
     inline void setBrush(ColorRole role, const QBrush &brush) { _uiStylePalette[(int)role] = brush; }
 
     inline const QBrush &brush(ColorRole role) const { return _uiStylePalette.at((int)role); }
     inline void setBrush(ColorRole role, const QBrush &brush) { _uiStylePalette[(int)role] = brush; }
@@ -253,10 +264,10 @@ protected:
     QString loadStyleSheet(const QString &name, bool shouldExist = false);
 
     QTextCharFormat format(quint64 key) const;
     QString loadStyleSheet(const QString &name, bool shouldExist = false);
 
     QTextCharFormat format(quint64 key) const;
-    QTextCharFormat cachedFormat(quint32 formatType, quint32 messageLabel) const;
-    void setCachedFormat(const QTextCharFormat &format, quint32 formatType, quint32 messageLabel) const;
-    void mergeFormat(QTextCharFormat &format, quint32 formatType, quint64 messageLabel) const;
-    void mergeSubElementFormat(QTextCharFormat &format, quint32 formatType, quint64 messageLabel) const;
+    QTextCharFormat cachedFormat(FormatType formatType, MessageLabel messageLabel) const;
+    void setCachedFormat(const QTextCharFormat &format, FormatType formatType, MessageLabel messageLabel) const;
+    void mergeFormat(QTextCharFormat &format, FormatType formatType, MessageLabel messageLabel) const;
+    void mergeSubElementFormat(QTextCharFormat &format, FormatType formatType, MessageLabel messageLabel) const;
 
     static FormatType formatType(const QString &code);
     static QString formatCode(FormatType);
 
     static FormatType formatType(const QString &code);
     static QString formatCode(FormatType);
@@ -310,7 +321,7 @@ private:
     QHash<quint64, QTextCharFormat> _formats;
     mutable QHash<quint64, QTextCharFormat> _formatCache;
     mutable QHash<quint64, QFontMetricsF *> _metricsCache;
     QHash<quint64, QTextCharFormat> _formats;
     mutable QHash<quint64, QTextCharFormat> _formatCache;
     mutable QHash<quint64, QFontMetricsF *> _metricsCache;
-    QHash<quint32, QTextCharFormat> _listItemFormats;
+    QHash<UiStyle::ItemFormatType, QTextCharFormat> _listItemFormats;
     static QHash<QString, FormatType> _formatCodes;
     static bool _useCustomTimestampFormat;        /// If true, use the custom timestamp format
     static QString _systemTimestampFormatString;  /// Cached copy of system locale timestamp format
     static QHash<QString, FormatType> _formatCodes;
     static bool _useCustomTimestampFormat;        /// If true, use the custom timestamp format
     static QString _systemTimestampFormatString;  /// Cached copy of system locale timestamp format
@@ -357,10 +368,39 @@ private:
     mutable quint8 _senderHash;
 };
 
     mutable quint8 _senderHash;
 };
 
+#if QT_VERSION < 0x050000
+uint qHash(UiStyle::ItemFormatType key);
+#else
+uint qHash(UiStyle::ItemFormatType key, uint seed);
+#endif
+
+// ---- Operators for dealing with enums ----------------------------------------------------------
+
+UiStyle::FormatType operator|(UiStyle::FormatType lhs, UiStyle::FormatType rhs);
+UiStyle::FormatType& operator|=(UiStyle::FormatType &lhs, UiStyle::FormatType rhs);
+UiStyle::FormatType operator|(UiStyle::FormatType lhs, quint32 rhs);
+UiStyle::FormatType& operator|=(UiStyle::FormatType &lhs, quint32 rhs);
+UiStyle::FormatType operator&(UiStyle::FormatType lhs, UiStyle::FormatType rhs);
+UiStyle::FormatType& operator&=(UiStyle::FormatType &lhs, UiStyle::FormatType rhs);
+UiStyle::FormatType operator&(UiStyle::FormatType lhs, quint32 rhs);
+UiStyle::FormatType& operator&=(UiStyle::FormatType &lhs, quint32 rhs);
+UiStyle::FormatType& operator^=(UiStyle::FormatType &lhs, UiStyle::FormatType rhs);
+
+UiStyle::MessageLabel operator|(UiStyle::MessageLabel lhs, UiStyle::MessageLabel rhs);
+UiStyle::MessageLabel& operator|=(UiStyle::MessageLabel &lhs, UiStyle::MessageLabel rhs);
+UiStyle::MessageLabel operator&(UiStyle::MessageLabel lhs, quint32 rhs);
+UiStyle::MessageLabel& operator&=(UiStyle::MessageLabel &lhs, UiStyle::MessageLabel rhs);
+
+// Shifts the label into the upper half of the return value
+quint64 operator|(UiStyle::FormatType lhs, UiStyle::MessageLabel rhs);
+
+UiStyle::ItemFormatType operator|(UiStyle::ItemFormatType lhs, UiStyle::ItemFormatType rhs);
+UiStyle::ItemFormatType& operator|=(UiStyle::ItemFormatType &lhs, UiStyle::ItemFormatType rhs);
+
+// ---- Allow for FormatList in QVariant ----------------------------------------------------------
 
 QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList);
 QDataStream &operator>>(QDataStream &in, UiStyle::FormatList &formatList);
 
 Q_DECLARE_METATYPE(UiStyle::FormatList)
 
 QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList);
 QDataStream &operator>>(QDataStream &in, UiStyle::FormatList &formatList);
 
 Q_DECLARE_METATYPE(UiStyle::FormatList)
-
-#endif
+Q_DECLARE_METATYPE(UiStyle::MessageLabel)