The background color (set by UiStyle) is now available in the MessageModel
via the BackgroundRole. It is used by the items to paint themselves, if it is
set by a stylesheet.
Message labels (so far, we support "highlight" and "own message") are also respected
properly. They can be accessed via the MsgLabelRole and are now used for accessing the style
engine.
enum MessageRole {
DisplayRole = Qt::DisplayRole,
EditRole = Qt::EditRole,
enum MessageRole {
DisplayRole = Qt::DisplayRole,
EditRole = Qt::EditRole,
+ BackgroundRole = Qt::BackgroundRole,
MsgIdRole = Qt::UserRole,
BufferIdRole,
TypeRole,
MsgIdRole = Qt::UserRole,
BufferIdRole,
TypeRole,
layout->setTextOption(option);
QList<QTextLayout::FormatRange> formatRanges
layout->setTextOption(option);
QList<QTextLayout::FormatRange> formatRanges
- = QtUi::style()->toTextLayoutList(data(MessageModel::FormatRole).value<UiStyle::FormatList>(), layout->text().length());
+ = QtUi::style()->toTextLayoutList(data(MessageModel::FormatRole).value<UiStyle::FormatList>(), layout->text().length(), data(ChatLineModel::MsgLabelRole).toUInt());
layout->setAdditionalFormats(formatRanges);
}
layout->setAdditionalFormats(formatRanges);
}
void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
Q_UNUSED(option); Q_UNUSED(widget);
painter->setClipRect(boundingRect()); // no idea why QGraphicsItem clipping won't work
void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
Q_UNUSED(option); Q_UNUSED(widget);
painter->setClipRect(boundingRect()); // no idea why QGraphicsItem clipping won't work
+
+ QVariant bgBrush = data(ChatLineModel::BackgroundRole);
+ if(bgBrush.isValid())
+ painter->fillRect(boundingRect(), bgBrush.value<QBrush>());
+
QVector<QTextLayout::FormatRange> formats = additionalFormats();
QTextLayout::FormatRange selectFmt = selectionFormat();
if(selectFmt.format.isValid()) formats.append(selectFmt);
QVector<QTextLayout::FormatRange> formats = additionalFormats();
QTextLayout::FormatRange selectFmt = selectionFormat();
if(selectFmt.format.isValid()) formats.append(selectFmt);
Q_UNUSED(option); Q_UNUSED(widget);
painter->setClipRect(boundingRect()); // no idea why QGraphicsItem clipping won't work
Q_UNUSED(option); Q_UNUSED(widget);
painter->setClipRect(boundingRect()); // no idea why QGraphicsItem clipping won't work
+
+ QVariant bgBrush = data(ChatLineModel::BackgroundRole);
+ if(bgBrush.isValid())
+ painter->fillRect(boundingRect(), bgBrush.value<QBrush>());
+
QTextLayout layout;
initLayout(&layout);
qreal layoutWidth = layout.minimumWidth();
QTextLayout layout;
initLayout(&layout);
qreal layoutWidth = layout.minimumWidth();
void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
Q_UNUSED(option);
Q_UNUSED(widget);
void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
Q_UNUSED(option);
Q_UNUSED(widget);
- if(_selection & Highlighted) {
- painter->fillRect(boundingRect(), QBrush(QtUi::style()->highlightColor()));
+
+ 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();
+
+ QTextCharFormat msgFmt = QtUi::style()->format(UiStyle::formatType(type), label);
+ if(msgFmt.hasProperty(QTextFormat::BackgroundBrush)) {
+ painter->fillRect(boundingRect(), msgFmt.background());
+
+ // TODO make this dependent on the style engine (highlight-color & friends)
if(_selection & Selected) {
qreal left = item((ChatLineModel::ColumnType)(_selection & ItemMask)).x();
QRectF selectRect(left, 0, width() - left, height());
if(_selection & Selected) {
qreal left = item((ChatLineModel::ColumnType)(_selection & ItemMask)).x();
QRectF selectRect(left, 0, width() - left, height());
- const QAbstractItemModel *model_ = model();
if(model_ && row() > 0 && chatScene()->isSingleBufferScene()) {
QModelIndex prevRowIdx = model_->index(row() - 1, 0);
if(model_ && row() > 0 && chatScene()->isSingleBufferScene()) {
QModelIndex prevRowIdx = model_->index(row() - 1, 0);
- MsgId prevMsgId = model_->data(prevRowIdx, MessageModel::MsgIdRole).value<MsgId>();
- QModelIndex myIdx = model_->index(row(), 0);
- MsgId myMsgId = model_->data(myIdx, MessageModel::MsgIdRole).value<MsgId>();
- Message::Flags flags = (Message::Flags)model_->data(myIdx, MessageModel::FlagsRole).toInt();
+ MsgId prevMsgId = prevRowIdx.data(MessageModel::MsgIdRole).value<MsgId>();
+ MsgId myMsgId = myIdx.data(MessageModel::MsgIdRole).value<MsgId>();
+ Message::Flags flags = (Message::Flags)myIdx.data(MessageModel::FlagsRole).toInt();
+
// don't show the marker if we wrote that new line
if(!(flags & Message::Self)) {
BufferId bufferId = BufferId(chatScene()->idString().toInt());
MsgId lastSeenMsgId = Client::networkModel()->lastSeenMarkerMsgId(bufferId);
if(lastSeenMsgId < myMsgId && lastSeenMsgId >= prevMsgId) {
// don't show the marker if we wrote that new line
if(!(flags & Message::Self)) {
BufferId bufferId = BufferId(chatScene()->idString().toInt());
MsgId lastSeenMsgId = Client::networkModel()->lastSeenMarkerMsgId(bufferId);
if(lastSeenMsgId < myMsgId && lastSeenMsgId >= prevMsgId) {
- QtUiStyleSettings s("Colors");
- QLinearGradient gradient(0, 0, 0, contentsItem().fontMetrics()->lineSpacing());
- gradient.setColorAt(0, s.value("newMsgMarkerFG", QColor(Qt::red)).value<QColor>());
- gradient.setColorAt(0.1, Qt::transparent);
- painter->fillRect(boundingRect(), gradient);
+ QtUiStyleSettings s("Colors");
+ QLinearGradient gradient(0, 0, 0, contentsItem().fontMetrics()->lineSpacing());
+ gradient.setColorAt(0, s.value("newMsgMarkerFG", QColor(Qt::red)).value<QColor>());
+ gradient.setColorAt(0.1, Qt::transparent);
+ painter->fillRect(boundingRect(), gradient);
public:
enum ChatLineRole {
public:
enum ChatLineRole {
- WrapListRole = MessageModel::UserRole
+ WrapListRole = MessageModel::UserRole,
+ MsgLabelRole
};
ChatLineModel(QObject *parent = 0);
};
ChatLineModel(QObject *parent = 0);
}
QVariant ChatLineModelItem::data(int column, int role) const {
}
QVariant ChatLineModelItem::data(int column, int role) const {
- MessageModel::ColumnType col = (MessageModel::ColumnType)column;
+ if(role == ChatLineModel::MsgLabelRole)
+ return messageLabel();
+
+ MessageModel::ColumnType col = (MessageModel::ColumnType)column;
switch(col) {
case ChatLineModel::TimestampColumn:
variant = timestampData(role);
switch(col) {
case ChatLineModel::TimestampColumn:
variant = timestampData(role);
return _styledMsg.decoratedTimestamp();
case ChatLineModel::EditRole:
return _styledMsg.timestamp();
return _styledMsg.decoratedTimestamp();
case ChatLineModel::EditRole:
return _styledMsg.timestamp();
+ case ChatLineModel::BackgroundRole:
+ return backgroundBrush(UiStyle::Timestamp);
case ChatLineModel::FormatRole:
case ChatLineModel::FormatRole:
- return QVariant::fromValue<UiStyle::FormatList>(UiStyle::FormatList() << qMakePair((quint16)0, (quint32)_styledMsg.timestampFormat()));
+ return QVariant::fromValue<UiStyle::FormatList>(UiStyle::FormatList()
+ << qMakePair((quint16)0, (quint32)UiStyle::formatType(_styledMsg.type()) | UiStyle::Timestamp));
return _styledMsg.decoratedSender();
case ChatLineModel::EditRole:
return _styledMsg.plainSender();
return _styledMsg.decoratedSender();
case ChatLineModel::EditRole:
return _styledMsg.plainSender();
+ case ChatLineModel::BackgroundRole:
+ return backgroundBrush(UiStyle::Sender);
case ChatLineModel::FormatRole:
case ChatLineModel::FormatRole:
- return QVariant::fromValue<UiStyle::FormatList>(UiStyle::FormatList() << qMakePair((quint16)0, (quint32)_styledMsg.senderFormat()));
+ return QVariant::fromValue<UiStyle::FormatList>(UiStyle::FormatList()
+ << qMakePair((quint16)0, (quint32)UiStyle::formatType(_styledMsg.type()) | UiStyle::Sender));
}
return QVariant();
}
QVariant ChatLineModelItem::contentsData(int role) const {
}
return QVariant();
}
QVariant ChatLineModelItem::contentsData(int role) const {
- if(_styledMsg.needsStyling())
- _styledMsg.style(QtUi::style());
-
switch(role) {
case ChatLineModel::DisplayRole:
case ChatLineModel::EditRole:
return _styledMsg.plainContents();
switch(role) {
case ChatLineModel::DisplayRole:
case ChatLineModel::EditRole:
return _styledMsg.plainContents();
+ case ChatLineModel::BackgroundRole:
+ return backgroundBrush(UiStyle::Contents);
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:
+quint32 ChatLineModelItem::messageLabel() const {
+ quint32 label = 0;
+ if(_styledMsg.flags() & Message::Self)
+ label |= UiStyle::OwnMsg;
+ if(_styledMsg.flags() & Message::Highlight)
+ label |= UiStyle::Highlight;
+ return label;
+}
+
+QVariant ChatLineModelItem::backgroundBrush(UiStyle::FormatType subelement) const {
+ QTextCharFormat fmt = QtUi::style()->format(UiStyle::formatType(_styledMsg.type()) | subelement, messageLabel());
+ if(fmt.hasProperty(QTextFormat::BackgroundBrush))
+ return QVariant::fromValue<QBrush>(fmt.background());
+ return QVariant();
+}
+
void ChatLineModelItem::computeWrapList() const {
int length = _styledMsg.plainContents().length();
if(!length)
void ChatLineModelItem::computeWrapList() const {
int length = _styledMsg.plainContents().length();
if(!length)
option.setWrapMode(QTextOption::NoWrap);
layout.setTextOption(option);
option.setWrapMode(QTextOption::NoWrap);
layout.setTextOption(option);
- layout.setAdditionalFormats(QtUi::style()->toTextLayoutList(_styledMsg.contentsFormatList(), length));
+ layout.setAdditionalFormats(QtUi::style()->toTextLayoutList(_styledMsg.contentsFormatList(), length, messageLabel()));
layout.beginLayout();
QTextLine line = layout.createLine();
line.setNumColumns(length);
layout.beginLayout();
QTextLine line = layout.createLine();
line.setNumColumns(length);
typedef QVector<Word> WrapList;
private:
typedef QVector<Word> WrapList;
private:
- virtual QVariant timestampData(int role) const;
- virtual QVariant senderData(int role) const;
- virtual QVariant contentsData(int role) const;
+ QVariant timestampData(int role) const;
+ QVariant senderData(int role) const;
+ QVariant contentsData(int role) const;
+
+ QVariant backgroundBrush(UiStyle::FormatType subelement) const;
+ quint32 messageLabel() const;
void computeWrapList() const;
void computeWrapList() const;
return _formatCodes.key(ftype);
}
return _formatCodes.key(ftype);
}
-QList<QTextLayout::FormatRange> UiStyle::toTextLayoutList(const FormatList &formatList, int textLength) {
+QList<QTextLayout::FormatRange> UiStyle::toTextLayoutList(const FormatList &formatList, int textLength, quint32 messageLabel) {
QList<QTextLayout::FormatRange> formatRanges;
QTextLayout::FormatRange range;
int i = 0;
for(i = 0; i < formatList.count(); i++) {
QList<QTextLayout::FormatRange> formatRanges;
QTextLayout::FormatRange range;
int i = 0;
for(i = 0; i < formatList.count(); i++) {
- range.format = format(formatList.at(i).second);
+ range.format = format(formatList.at(i).second, messageLabel);
range.start = formatList.at(i).first;
if(i > 0) formatRanges.last().length = range.start - formatRanges.last().start;
formatRanges.append(range);
range.start = formatList.at(i).first;
if(i > 0) formatRanges.last().length = range.start - formatRanges.last().start;
formatRanges.append(range);
inline QFont defaultFont() const { return _defaultFont; }
inline QFont defaultFont() const { return _defaultFont; }
- QList<QTextLayout::FormatRange> toTextLayoutList(const FormatList &, int textLength);
+ QList<QTextLayout::FormatRange> toTextLayoutList(const FormatList &, int textLength, quint32 messageLabel = 0);
protected:
void loadStyleSheet();
protected:
void loadStyleSheet();