-bool UiStyle::_useCustomTimestampFormat; /// If true, use the custom timestamp format
-QString UiStyle::_timestampFormatString; /// Timestamp format
-QString UiStyle::_systemTimestampFormatString; /// Cached copy of system locale timestamp format
-bool UiStyle::_showSenderBrackets; /// If true, show brackets around sender names
-
-UiStyle::UiStyle(QObject *parent)
- : QObject(parent),
- _channelJoinedIcon(QIcon::fromTheme("irc-channel-joined", QIcon(":/icons/irc-channel-joined.png"))),
- _channelPartedIcon(QIcon::fromTheme("irc-channel-parted", QIcon(":/icons/irc-channel-parted.png"))),
- _userOfflineIcon(QIcon::fromTheme("im-user-offline", QIcon::fromTheme("user-offline", QIcon(":/icons/im-user-offline.png")))),
- _userOnlineIcon(QIcon::fromTheme("im-user", QIcon::fromTheme("user-available", QIcon(":/icons/im-user.png")))), // im-user-* are non-standard oxygen extensions
- _userAwayIcon(QIcon::fromTheme("im-user-away", QIcon::fromTheme("user-away", QIcon(":/icons/im-user-away.png")))),
- _categoryOpIcon(QIcon::fromTheme("irc-operator")),
- _categoryVoiceIcon(QIcon::fromTheme("irc-voice")),
- _opIconLimit(UserCategoryItem::categoryFromModes("o")),
- _voiceIconLimit(UserCategoryItem::categoryFromModes("v"))
-{
- // register FormatList if that hasn't happened yet
- // FIXME I don't think this actually avoids double registration... then again... does it hurt?
- if (QVariant::nameToType("UiStyle::FormatList") == QVariant::Invalid) {
- qRegisterMetaType<FormatList>("UiStyle::FormatList");
- qRegisterMetaTypeStreamOperators<FormatList>("UiStyle::FormatList");
- Q_ASSERT(QVariant::nameToType("UiStyle::FormatList") != QVariant::Invalid);
- }
-
- _uiStylePalette = QVector<QBrush>(NumRoles, QBrush());
+bool UiStyle::_useCustomTimestampFormat; /// If true, use the custom timestamp format
+QString UiStyle::_timestampFormatString; /// Timestamp format
+QString UiStyle::_systemTimestampFormatString; /// Cached copy of system locale timestamp format
+UiStyle::SenderPrefixMode UiStyle::_senderPrefixDisplay; /// Display of prefix modes before sender
+bool UiStyle::_showSenderBrackets; /// If true, show brackets around sender names
+
+namespace {
+
+// Extended mIRC colors as defined in https://modern.ircdocs.horse/formatting.html#colors-16-98
+QColor extendedMircColor(int number)
+{
+ static const std::vector<QColor> colorMap = {"#470000", "#472100", "#474700", "#324700", "#004700", "#00472c", "#004747", "#002747",
+ "#000047", "#2e0047", "#470047", "#47002a", "#740000", "#743a00", "#747400", "#517400",
+ "#007400", "#007449", "#007474", "#004074", "#000074", "#4b0074", "#740074", "#740045",
+ "#b50000", "#b56300", "#b5b500", "#7db500", "#00b500", "#00b571", "#00b5b5", "#0063b5",
+ "#0000b5", "#7500b5", "#b500b5", "#b5006b", "#ff0000", "#ff8c00", "#ffff00", "#b2ff00",
+ "#00ff00", "#00ffa0", "#00ffff", "#008cff", "#0000ff", "#a500ff", "#ff00ff", "#ff0098",
+ "#ff5959", "#ffb459", "#ffff71", "#cfff60", "#6fff6f", "#65ffc9", "#6dffff", "#59b4ff",
+ "#5959ff", "#c459ff", "#ff66ff", "#ff59bc", "#ff9c9c", "#ffd39c", "#ffff9c", "#e2ff9c",
+ "#9cff9c", "#9cffdb", "#9cffff", "#9cd3ff", "#9c9cff", "#dc9cff", "#ff9cff", "#ff94d3",
+ "#000000", "#131313", "#282828", "#363636", "#4d4d4d", "#656565", "#818181", "#9f9f9f",
+ "#bcbcbc", "#e2e2e2", "#ffffff"};
+ if (number < 16)
+ return {};
+ size_t index = number - 16;
+ return (index < colorMap.size() ? colorMap[index] : QColor{});
+}
+
+} // namespace
+
+UiStyle::UiStyle(QObject* parent)
+ : QObject(parent)
+ , _channelJoinedIcon{icon::get("irc-channel-active")}
+ , _channelPartedIcon{icon::get("irc-channel-inactive")}
+ , _userOfflineIcon{icon::get({"im-user-offline", "user-offline"})}
+ , _userOnlineIcon{icon::get({"im-user-online", "im-user", "user-available"})}
+ , _userAwayIcon{icon::get({"im-user-away", "user-away"})}
+ , _categoryOpIcon{icon::get("irc-operator")}
+ , _categoryVoiceIcon{icon::get("irc-voice")}
+ , _opIconLimit{UserCategoryItem::categoryFromModes("o")}
+ , _voiceIconLimit{UserCategoryItem::categoryFromModes("v")}
+{
+ static bool registered = []() {
+ qRegisterMetaType<FormatList>();
+ qRegisterMetaTypeStreamOperators<FormatList>();
+ return true;
+ }();
+ Q_UNUSED(registered)
+
+ _uiStylePalette = QVector<QBrush>(static_cast<int>(ColorRole::NumRoles), QBrush());