From: Manuel Nickschas Date: Fri, 13 Jun 2008 23:42:08 +0000 (+0200) Subject: Compute correct height of ChatItems. X-Git-Tag: 0.3.0~182 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=3a9668461efb05bd5b24ba5eb741a7f7f75086c9;hp=bedd08ea58926e41e6ad1d0bf256a97cae97fb3c Compute correct height of ChatItems. For this, we precompute possible wrap points and the width of words, form which we can quickly compute the height. --- diff --git a/src/client/messagemodel.cpp b/src/client/messagemodel.cpp index 6784c4fe..76104bd2 100644 --- a/src/client/messagemodel.cpp +++ b/src/client/messagemodel.cpp @@ -34,8 +34,9 @@ MessageModel::~MessageModel() { } QVariant MessageModel::data(const QModelIndex &index, int role) const { - int row = index.row(); - if(row < 0 || row >= _messageList.count()) return QVariant(); + int row = index.row(); int column = index.column(); + if(row < 0 || row >= _messageList.count() || column < 0) return QVariant(); + if(role == ColumnTypeRole) return column; return _messageList[row]->data(index.column(), role); } diff --git a/src/client/messagemodel.h b/src/client/messagemodel.h index 5b2786aa..f6e2538f 100644 --- a/src/client/messagemodel.h +++ b/src/client/messagemodel.h @@ -42,6 +42,7 @@ class MessageModel : public QAbstractItemModel { TimestampRole, DisplayRole, FormatRole, + ColumnTypeRole, UserRole }; diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index 63d92e68..568cdccf 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -26,9 +26,12 @@ #include #include "chatitem.h" +#include "chatlinemodel.h" +#include "qtui.h" ChatItem::ChatItem(const QPersistentModelIndex &index_, QGraphicsItem *parent) : QGraphicsItem(parent), _index(index_) { - + QFontMetricsF *metrics = QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value().at(0).second); + _lineHeight = metrics->lineSpacing(); } ChatItem::~ChatItem() { @@ -57,12 +60,33 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->drawRect(boundingRect()); } - - int ChatItem::setWidth(int w) { + if(w == _boundingRect.width()) return _boundingRect.height(); + int h = heightForWidth(w); _boundingRect.setWidth(w); - _boundingRect.setHeight(20); // FIXME - return 20; + _boundingRect.setHeight(h); + return h; +} + +int ChatItem::heightForWidth(int width) { + if(data(ChatLineModel::ColumnTypeRole).toUInt() != ChatLineModel::ContentsColumn) + return _lineHeight; // only contents can be multi-line + + QVariantList wrapList = data(ChatLineModel::WrapListRole).toList(); + int lines = 1; + int offset = 0; + for(int i = 0; i < wrapList.count(); i+=2) { + if(wrapList.at(i+1).toUInt() - offset < width) continue; + lines++; + if(i > 0) { + if(offset != wrapList.at(i-1).toUInt()) offset = wrapList.at(i-1).toUInt(); + else offset += width; + } else { + offset += width; + } + i-=2; + } + return lines * _lineHeight; } /* diff --git a/src/qtui/chatitem.h b/src/qtui/chatitem.h index 97a6fc06..55985a39 100644 --- a/src/qtui/chatitem.h +++ b/src/qtui/chatitem.h @@ -18,8 +18,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _CHATITEM_H_ -#define _CHATITEM_H_ +#ifndef CHATITEM_H_ +#define CHATITEM_H_ #include #include @@ -57,6 +57,9 @@ class ChatItem : public QGraphicsItem { //void mouseMoveEvent ( QGraphicsSceneMouseEvent * event ); private: + int heightForWidth(int width); + + int _lineHeight; QRectF _boundingRect; //QTextLayout _layout; //QTextOption _textOption; diff --git a/src/qtui/chatlinemodel.h b/src/qtui/chatlinemodel.h index b61bd66b..779b5f2a 100644 --- a/src/qtui/chatlinemodel.h +++ b/src/qtui/chatlinemodel.h @@ -28,7 +28,7 @@ class ChatLineModel : public MessageModel { public: enum ChatLineRole { - FormatRole = MessageModel::UserRole + WrapListRole = MessageModel::UserRole }; ChatLineModel(QObject *parent = 0); diff --git a/src/qtui/chatlinemodelitem.cpp b/src/qtui/chatlinemodelitem.cpp index 8d15b92c..b657f397 100644 --- a/src/qtui/chatlinemodelitem.cpp +++ b/src/qtui/chatlinemodelitem.cpp @@ -37,7 +37,7 @@ ChatLineModelItem::ChatLineModelItem(const Message &msg) : MessageModelItem(msg) _sender.formatList = m.sender.formatList; _contents.formatList = m.contents.formatList; - computeWordList(); + computeWrapList(); } @@ -52,8 +52,16 @@ QVariant ChatLineModelItem::data(int column, int role) const { } switch(role) { - case ChatLineModel::DisplayRole: return part->plainText; - case ChatLineModel::FormatRole: return QVariant::fromValue(part->formatList); + case ChatLineModel::DisplayRole: + return part->plainText; + case ChatLineModel::FormatRole: + return QVariant::fromValue(part->formatList); + case ChatLineModel::WrapListRole: + if(column != ChatLineModel::ContentsColumn) return QVariant(); + QVariantList wrapList; + typedef QPair WrapPoint; // foreach can't parse templated params + foreach(WrapPoint pair, _wrapList) wrapList << pair.first << pair.second; + return wrapList; } return MessageModelItem::data(column, role); @@ -63,8 +71,8 @@ bool ChatLineModelItem::setData(int column, const QVariant &value, int role) { return false; } -void ChatLineModelItem::computeWordList() { - QList > wplist; // use a temp list which we'll later copy into a QVector for efficiency +void ChatLineModelItem::computeWrapList() { + WrapList wplist; // use a temp list which we'll later copy into a QVector for efficiency QTextBoundaryFinder finder(QTextBoundaryFinder::Word, _contents.plainText); int idx; int flistidx = -1; @@ -93,9 +101,9 @@ void ChatLineModelItem::computeWordList() { } while(idx < _contents.plainText.length()); // A QVector needs less space than a QList - _wordList.resize(wplist.count()); + _wrapList.resize(wplist.count()); for(int i = 0; i < wplist.count(); i++) { - _wordList[i] = wplist.at(i); + _wrapList[i] = wplist.at(i); } } diff --git a/src/qtui/chatlinemodelitem.h b/src/qtui/chatlinemodelitem.h index 24fed2be..f01b4e1d 100644 --- a/src/qtui/chatlinemodelitem.h +++ b/src/qtui/chatlinemodelitem.h @@ -37,7 +37,9 @@ class ChatLineModelItem : public MessageModelItem { virtual bool setData(int column, const QVariant &value, int role); private: - void computeWordList(); + typedef QVector > WrapList; + + void computeWrapList(); struct ChatLinePart { QString plainText; @@ -45,7 +47,7 @@ class ChatLineModelItem : public MessageModelItem { }; ChatLinePart _timestamp, _sender, _contents; - QVector > _wordList; + WrapList _wrapList; }; #endif