Make backgrounds of ChatLines and ChatItems styleable
authorManuel Nickschas <sputnick@quassel-irc.org>
Sun, 21 Jun 2009 19:23:40 +0000 (21:23 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Thu, 6 Aug 2009 18:25:05 +0000 (20:25 +0200)
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.

src/client/messagemodel.h
src/qtui/chatitem.cpp
src/qtui/chatline.cpp
src/qtui/chatlinemodel.h
src/qtui/chatlinemodelitem.cpp
src/qtui/chatlinemodelitem.h
src/uisupport/uistyle.cpp
src/uisupport/uistyle.h

index b6b783f..2e30dd2 100644 (file)
@@ -37,6 +37,7 @@ public:
   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,
index d58ab0b..5c44815 100644 (file)
@@ -69,7 +69,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(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);
 }
 
@@ -89,6 +89,11 @@ void ChatItem::doLayout(QTextLayout *layout) const {
 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);
@@ -300,6 +305,11 @@ void SenderChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *op
   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();
index 278c1de..1c7db84 100644 (file)
@@ -154,9 +154,18 @@ void ChatLine::setHighlighted(bool highlighted) {
 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());
@@ -164,23 +173,22 @@ void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
   }
 
   // new line marker
   }
 
   // new line marker
-  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);
       }
     }
   }
       }
     }
   }
index 12770d2..dffb706 100644 (file)
@@ -31,7 +31,8 @@ class ChatLineModel : public MessageModel {
 
 public:
   enum ChatLineRole {
 
 public:
   enum ChatLineRole {
-    WrapListRole = MessageModel::UserRole
+    WrapListRole = MessageModel::UserRole,
+    MsgLabelRole
   };
 
   ChatLineModel(QObject *parent = 0);
   };
 
   ChatLineModel(QObject *parent = 0);
index 2264fa5..0bcc7a7 100644 (file)
@@ -53,8 +53,11 @@ ChatLineModelItem::ChatLineModelItem(const Message &msg)
 }
 
 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();
+
   QVariant variant;
   QVariant variant;
+  MessageModel::ColumnType col = (MessageModel::ColumnType)column;
   switch(col) {
   case ChatLineModel::TimestampColumn:
     variant = timestampData(role);
   switch(col) {
   case ChatLineModel::TimestampColumn:
     variant = timestampData(role);
@@ -79,8 +82,11 @@ QVariant ChatLineModelItem::timestampData(int role) const {
     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 QVariant();
 }
   }
   return QVariant();
 }
@@ -91,20 +97,22 @@ QVariant ChatLineModelItem::senderData(int role) const {
     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:
@@ -115,6 +123,22 @@ QVariant ChatLineModelItem::contentsData(int role) const {
   return QVariant();
 }
 
   return QVariant();
 }
 
+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)
@@ -140,7 +164,7 @@ void ChatLineModelItem::computeWrapList() const {
   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);
index 5382a7b..a553cca 100644 (file)
@@ -49,9 +49,12 @@ public:
   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;
 
index a29d0c5..80a29b2 100644 (file)
@@ -181,12 +181,12 @@ QString UiStyle::formatCode(FormatType ftype) {
   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);
index 5941515..22ade27 100644 (file)
@@ -112,7 +112,7 @@ public:
 
   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();