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);
}
}
-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 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;
// 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.insert(i, fmtList.at(i));
+ fmtList.insert(fmtList.begin() + i, fmtList.at(i));
fmtList[i+1].first = end;
}
- fmtList[i].second |= overlayFmt;
+ fmtList[i].second.type |= overlayFmt;
}
}
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();
}
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);
}
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;
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; }
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)) {
}
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());
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;
case ChatLineModel::EditRole:
return _styledMsg.timestamp();
case ChatLineModel::BackgroundRole:
- return backgroundBrush(UiStyle::Timestamp);
+ return backgroundBrush(UiStyle::FormatType::Timestamp);
case ChatLineModel::SelectedBackgroundRole:
- return backgroundBrush(UiStyle::Timestamp, true);
+ return backgroundBrush(UiStyle::FormatType::Timestamp, true);
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();
}
case ChatLineModel::EditRole:
return _styledMsg.plainSender();
case ChatLineModel::BackgroundRole:
- return backgroundBrush(UiStyle::Sender);
+ return backgroundBrush(UiStyle::FormatType::Sender);
case ChatLineModel::SelectedBackgroundRole:
- return backgroundBrush(UiStyle::Sender, true);
+ return backgroundBrush(UiStyle::FormatType::Sender, true);
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();
}
case ChatLineModel::EditRole:
return _styledMsg.plainContents();
case ChatLineModel::BackgroundRole:
- return backgroundBrush(UiStyle::Contents);
+ return backgroundBrush(UiStyle::FormatType::Contents);
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:
}
-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)
- label |= UiStyle::OwnMsg;
+ label |= MessageLabel::OwnMsg;
if (_styledMsg.flags() & Message::Highlight)
- label |= UiStyle::Highlight;
+ label |= MessageLabel::Highlight;
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();
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef CHATLINEMODELITEM_H_
-#define CHATLINEMODELITEM_H_
+#pragma once
#include "messagemodel.h"
QVariant contentsData(int role) const;
QVariant backgroundBrush(UiStyle::FormatType subelement, bool selected = false) const;
- quint32 messageLabel() const;
+ UiStyle::MessageLabel messageLabel() const;
void computeWrapList() const;
static unsigned char *TextBoundaryFinderBuffer;
static int TextBoundaryFinderBufferSize;
};
-
-
-#endif
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)
- 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);
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);
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
+#include <tuple>
+#include <utility>
+
#include <QApplication>
#include "qssparser.h"
_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
- _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;
}
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
- 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());
}
// 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);
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;
- _formats[fmtType].merge(parseFormat(contents));
+ _formats[fmtType|label].merge(parseFormat(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));
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;
_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);
/******** 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);
- return UiStyle::Invalid;
+ return invalid;
}
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")
- fmtType |= UiStyle::Timestamp;
+ fmtType |= FormatType::Timestamp;
else if (subElement == "sender")
- fmtType |= UiStyle::Sender;
+ fmtType |= FormatType::Sender;
else if (subElement == "nick")
- fmtType |= UiStyle::Nick;
+ fmtType |= FormatType::Nick;
else if (subElement == "contents")
- fmtType |= UiStyle::Contents;
+ fmtType |= FormatType::Contents;
else if (subElement == "hostmask")
- fmtType |= UiStyle::Hostmask;
+ fmtType |= FormatType::Hostmask;
else if (subElement == "modeflags")
- fmtType |= UiStyle::ModeFlags;
+ fmtType |= FormatType::ModeFlags;
else if (subElement == "url")
- fmtType |= UiStyle::Url;
+ fmtType |= FormatType::Url;
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")
- fmtType |= UiStyle::PlainMsg;
+ fmtType |= FormatType::PlainMsg;
else if (msgType == "notice")
- fmtType |= UiStyle::NoticeMsg;
+ fmtType |= FormatType::NoticeMsg;
else if (msgType == "action")
- fmtType |= UiStyle::ActionMsg;
+ fmtType |= FormatType::ActionMsg;
else if (msgType == "nick")
- fmtType |= UiStyle::NickMsg;
+ fmtType |= FormatType::NickMsg;
else if (msgType == "mode")
- fmtType |= UiStyle::ModeMsg;
+ fmtType |= FormatType::ModeMsg;
else if (msgType == "join")
- fmtType |= UiStyle::JoinMsg;
+ fmtType |= FormatType::JoinMsg;
else if (msgType == "part")
- fmtType |= UiStyle::PartMsg;
+ fmtType |= FormatType::PartMsg;
else if (msgType == "quit")
- fmtType |= UiStyle::QuitMsg;
+ fmtType |= FormatType::QuitMsg;
else if (msgType == "kick")
- fmtType |= UiStyle::KickMsg;
+ fmtType |= FormatType::KickMsg;
else if (msgType == "kill")
- fmtType |= UiStyle::KillMsg;
+ fmtType |= FormatType::KillMsg;
else if (msgType == "server")
- fmtType |= UiStyle::ServerMsg;
+ fmtType |= FormatType::ServerMsg;
else if (msgType == "info")
- fmtType |= UiStyle::InfoMsg;
+ fmtType |= FormatType::InfoMsg;
else if (msgType == "error")
- fmtType |= UiStyle::ErrorMsg;
+ fmtType |= FormatType::ErrorMsg;
else if (msgType == "daychange")
- fmtType |= UiStyle::DayChangeMsg;
+ fmtType |= FormatType::DayChangeMsg;
else if (msgType == "topic")
- fmtType |= UiStyle::TopicMsg;
+ fmtType |= FormatType::TopicMsg;
else if (msgType == "netsplit-join")
- fmtType |= UiStyle::NetsplitJoinMsg;
+ fmtType |= FormatType::NetsplitJoinMsg;
else if (msgType == "netsplit-quit")
- fmtType |= UiStyle::NetsplitQuitMsg;
+ fmtType |= FormatType::NetsplitQuitMsg;
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)
- 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);
- return UiStyle::Invalid;
+ return invalid;
}
QString condName = condRx.cap(1);
QString condValue = condRx.cap(2);
if (condName == "label") {
- quint64 labeltype = 0;
if (condValue == "highlight")
- labeltype = UiStyle::Highlight;
+ label |= MessageLabel::Highlight;
else if (condValue == "selected")
- labeltype = UiStyle::Selected;
+ label |= MessageLabel::Selected;
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")
- 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;
- 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);
- return UiStyle::Invalid;
+ return invalid;
}
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")
- fmtType |= UiStyle::Bold;
+ fmtType |= FormatType::Bold;
else if (condValue == "italic")
- fmtType |= UiStyle::Italic;
+ fmtType |= FormatType::Italic;
else if (condValue == "underline")
- fmtType |= UiStyle::Underline;
+ fmtType |= FormatType::Underline;
else if (condValue == "reverse")
- fmtType |= UiStyle::Reverse;
+ fmtType |= FormatType::Reverse;
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;
- 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);
- return UiStyle::Invalid;
+ return invalid;
}
if (condName == "fg-color")
- fmtType |= 0x00400000 | (quint32)(col << 24);
+ fmtType |= 0x00400000 | (col << 24);
else
- fmtType |= 0x00800000 | (quint32)(col << 28);
+ fmtType |= 0x00800000 | (col << 28);
}
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
-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);
- return UiStyle::Invalid;
+ return ItemFormatType::Invalid;
}
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;
- 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);
- return UiStyle::Invalid;
+ return ItemFormatType::Invalid;
}
props[propRx.cap(1)] = propRx.cap(2);
}
}
if (mainItemType == "Chat") {
- fmtType |= UiStyle::BufferViewItem;
+ fmtType |= ItemFormatType::BufferViewItem;
if (!type.isEmpty()) {
if (type == "network")
- fmtType |= UiStyle::NetworkItem;
+ fmtType |= ItemFormatType::NetworkItem;
else if (type == "channel")
- fmtType |= UiStyle::ChannelBufferItem;
+ fmtType |= ItemFormatType::ChannelBufferItem;
else if (type == "query")
- fmtType |= UiStyle::QueryBufferItem;
+ fmtType |= ItemFormatType::QueryBufferItem;
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")
- fmtType |= UiStyle::InactiveBuffer;
+ fmtType |= ItemFormatType::InactiveBuffer;
else if (state == "channel-event")
- fmtType |= UiStyle::ActiveBuffer;
+ fmtType |= ItemFormatType::ActiveBuffer;
else if (state == "unread-message")
- fmtType |= UiStyle::UnreadBuffer;
+ fmtType |= ItemFormatType::UnreadBuffer;
else if (state == "highlighted")
- fmtType |= UiStyle::HighlightedBuffer;
+ fmtType |= ItemFormatType::HighlightedBuffer;
else if (state == "away")
- fmtType |= UiStyle::UserAway;
+ fmtType |= ItemFormatType::UserAway;
else {
qWarning() << Q_FUNC_INFO << tr("Invalid chatlist state %1").arg(state);
- return UiStyle::Invalid;
+ return ItemFormatType::Invalid;
}
}
}
else { // NickList
- fmtType |= UiStyle::NickViewItem;
+ fmtType |= ItemFormatType::NickViewItem;
if (!type.isEmpty()) {
if (type == "user") {
- fmtType |= UiStyle::IrcUserItem;
+ fmtType |= ItemFormatType::IrcUserItem;
if (state == "away")
- fmtType |= UiStyle::UserAway;
+ fmtType |= ItemFormatType::UserAway;
}
else if (type == "category")
- fmtType |= UiStyle::UserCategoryItem;
+ fmtType |= ItemFormatType::UserCategoryItem;
}
}
return fmtType;
// [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 (_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")) {
- 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();
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();
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();
}
}
else {
- QRegExp rx("#?[0-9A-Fa-z]+");
+ static const QRegExp rx("#?[0-9A-Fa-z]+");
if (rx.exactMatch(str))
return QColor(str);
}
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();
}
{
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();
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;
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;
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef QSSPARSER_H_
-#define QSSPARSER_H_
+#pragma once
+
+#include <utility>
#include "uistyle.h"
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;
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);
QPalette _palette;
QVector<QBrush> _uiStylePalette;
QHash<quint64, QTextCharFormat> _formats;
- QHash<quint32, QTextCharFormat> _listItemFormats;
+ QHash<UiStyle::ItemFormatType, QTextCharFormat> _listItemFormats;
};
-
-
-#endif
{
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;
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)
{
- 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)
{
- removeLocalKey(QString("Format/%1").arg(ftype));
+ removeLocalKey(QString("Format/%1").arg(static_cast<quint32>(ftype)));
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
+#include <vector>
+
#include <QApplication>
#include <QIcon>
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...
- _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
}
}
- quint32 fmtType = BufferViewItem;
+ ItemFormatType fmtType = ItemFormatType::BufferViewItem;
switch (type) {
case BufferInfo::StatusBuffer:
- fmtType |= NetworkItem;
+ fmtType |= ItemFormatType::NetworkItem;
break;
case BufferInfo::ChannelBuffer:
- fmtType |= ChannelBufferItem;
+ fmtType |= ItemFormatType::ChannelBufferItem;
break;
case BufferInfo::QueryBuffer:
- fmtType |= QueryBufferItem;
+ fmtType |= ItemFormatType::QueryBufferItem;
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(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) {
- 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) {
- 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) {
- 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()) {
- 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);
}
}
- QTextCharFormat fmt = _listItemFormats.value(NickViewItem);
+ QTextCharFormat fmt = _listItemFormats.value(ItemFormatType::NickViewItem);
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()) {
- 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:
- fmt.merge(_listItemFormats.value(NickViewItem | UserCategoryItem));
+ fmt.merge(_listItemFormats.value(ItemFormatType::NickViewItem | ItemFormatType::UserCategoryItem));
break;
default:
return QVariant();
}
-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 :/
- quint64 key = ftype | ((quint64)label << 32);
+ quint64 key = ftype | label;
if (_metricsCache.contains(key))
return _metricsCache.value(key);
// 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
- QTextCharFormat fmt = cachedFormat(ftype, label_);
+ QTextCharFormat fmt = cachedFormat(ftype, label);
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;
}
-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"
- if ((ftype & 0xfff00)) { // element format
+ if ((ftype & 0xfff00) != FormatType::Base) { // element format
for (quint32 mask = 0x00100; mask <= 0x40000; mask <<= 1) {
- if (ftype & mask) {
+ if ((ftype & mask) != FormatType::Base) {
mergeSubElementFormat(fmt, ftype & (mask | 0xff), label);
}
}
// 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
- if (ftype & 0x00800000)
+ if ((ftype & 0x00800000) != FormatType::Base)
mergeSubElementFormat(fmt, ftype & 0xf0800000, label); // background
- if ((ftype & 0x00c00000) == 0x00c00000)
+ if ((ftype & 0x00c00000) == static_cast<FormatType>(0x00c00000))
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
-void UiStyle::mergeSubElementFormat(QTextCharFormat &fmt, quint32 ftype, quint64 label) const
+void UiStyle::mergeSubElementFormat(QTextCharFormat &fmt, FormatType ftype, MessageLabel label) const
{
quint64 key = ftype | label;
- fmt.merge(format(key & Q_UINT64_C(0x0000ffffffffff00))); // label + subelement
- fmt.merge(format(key & Q_UINT64_C(0x0000ffffffffffff))); // label + subelement + msgtype
- 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
}
{
switch (msgType) {
case Message::Plain:
- return PlainMsg;
+ return FormatType::PlainMsg;
case Message::Notice:
- return NoticeMsg;
+ return FormatType::NoticeMsg;
case Message::Action:
- return ActionMsg;
+ return FormatType::ActionMsg;
case Message::Nick:
- return NickMsg;
+ return FormatType::NickMsg;
case Message::Mode:
- return ModeMsg;
+ return FormatType::ModeMsg;
case Message::Join:
- return JoinMsg;
+ return FormatType::JoinMsg;
case Message::Part:
- return PartMsg;
+ return FormatType::PartMsg;
case Message::Quit:
- return QuitMsg;
+ return FormatType::QuitMsg;
case Message::Kick:
- return KickMsg;
+ return FormatType::KickMsg;
case Message::Kill:
- return KillMsg;
+ return FormatType::KillMsg;
case Message::Server:
- return ServerMsg;
+ return FormatType::ServerMsg;
case Message::Info:
- return InfoMsg;
+ return FormatType::InfoMsg;
case Message::Error:
- return ErrorMsg;
+ return FormatType::ErrorMsg;
case Message::DayChange:
- return DayChangeMsg;
+ return FormatType::DayChangeMsg;
case Message::Topic:
- return TopicMsg;
+ return FormatType::TopicMsg;
case Message::NetsplitJoin:
- return NetsplitJoinMsg;
+ return FormatType::NetsplitJoinMsg;
case Message::NetsplitQuit:
- return NetsplitQuitMsg;
+ return FormatType::NetsplitQuitMsg;
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;
- return ErrorMsg;
+ return FormatType::ErrorMsg;
}
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;
}
}
-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;
- 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;
- 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);
}
- 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.
-UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat)
+UiStyle::StyledString UiStyle::styleString(const QString &s_, FormatType baseFormat)
{
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
return result;
}
- quint32 curfmt = baseFormat;
+ FormatType curfmt = baseFormat;
+
int pos = 0; quint16 length = 0;
for (;;) {
pos = s.indexOf('%', pos);
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;
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
- result.formatList.append(qMakePair((quint16)pos, curfmt));
+ result.formatList.emplace_back(std::make_pair(pos, Format{curfmt}));
}
result.plainText = s;
return result;
return QString("<%1%2>").arg(_senderPrefixes, plainSender());
else
return QString("%1%2").arg(_senderPrefixes, plainSender());
- break;
case Message::Notice:
- return QString("[%1%2]").arg(_senderPrefixes, plainSender()); break;
+ return QString("[%1%2]").arg(_senderPrefixes, plainSender());
case Message::Action:
- return "-*-"; break;
+ return "-*-";
case Message::Nick:
- return "<->"; break;
+ return "<->";
case Message::Mode:
- return "***"; break;
+ return "***";
case Message::Join:
- return "-->"; break;
+ return "-->";
case Message::Part:
- return "<--"; break;
+ return "<--";
case Message::Quit:
- return "<--"; break;
+ return "<--";
case Message::Kick:
- return "<-*"; break;
+ return "<-*";
case Message::Kill:
- return "<-x"; break;
+ return "<-x";
case Message::Server:
- return "*"; break;
+ return "*";
case Message::Info:
- return "*"; break;
+ return "*";
case Message::Error:
- return "*"; break;
+ return "*";
case Message::DayChange:
- return "-"; break;
+ return "-";
case Message::Topic:
- return "*"; break;
+ return "*";
case Message::NetsplitJoin:
- return "=>"; break;
+ return "=>";
case Message::NetsplitQuit:
- return "<="; break;
+ return "<=";
case Message::Invite:
- return "->"; break;
- default:
- return QString("%1%2").arg(_senderPrefixes, plainSender());
+ return "->";
}
+
+ return QString("%1%2").arg(_senderPrefixes, plainSender());
}
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)
{
- out << formatList.count();
+ out << static_cast<quint16>(formatList.size());
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;
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;
}
* 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>
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.
* 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,
// background: 0x.0800000
};
- enum MessageLabel {
+ enum class MessageLabel : quint32 {
+ None = 0x00000000,
OwnMsg = 0x00000001,
Highlight = 0x00000002,
Selected = 0x00000004 // must be last!
};
- enum ItemFormatType {
+ enum class ItemFormatType : quint32 {
+ None = 0x00000000,
+
BufferViewItem = 0x00000001,
NickViewItem = 0x00000002,
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
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
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 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; }
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);
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
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)
-
-#endif
+Q_DECLARE_METATYPE(UiStyle::MessageLabel)