summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
bedd08e)
For this, we precompute possible wrap points and the width of words,
form which we can quickly compute the height.
}
QVariant MessageModel::data(const QModelIndex &index, int role) const {
}
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);
}
return _messageList[row]->data(index.column(), role);
}
TimestampRole,
DisplayRole,
FormatRole,
TimestampRole,
DisplayRole,
FormatRole,
#include <QtGui>
#include "chatitem.h"
#include <QtGui>
#include "chatitem.h"
+#include "chatlinemodel.h"
+#include "qtui.h"
ChatItem::ChatItem(const QPersistentModelIndex &index_, QGraphicsItem *parent) : QGraphicsItem(parent), _index(index_) {
ChatItem::ChatItem(const QPersistentModelIndex &index_, QGraphicsItem *parent) : QGraphicsItem(parent), _index(index_) {
+ QFontMetricsF *metrics = QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value<UiStyle::FormatList>().at(0).second);
+ _lineHeight = metrics->lineSpacing();
}
ChatItem::~ChatItem() {
}
ChatItem::~ChatItem() {
painter->drawRect(boundingRect());
}
painter->drawRect(boundingRect());
}
int ChatItem::setWidth(int w) {
int ChatItem::setWidth(int w) {
+ if(w == _boundingRect.width()) return _boundingRect.height();
+ int h = heightForWidth(w);
_boundingRect.setWidth(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;
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#ifndef _CHATITEM_H_
-#define _CHATITEM_H_
+#ifndef CHATITEM_H_
+#define CHATITEM_H_
#include <QGraphicsItem>
#include <QTextLayout>
#include <QGraphicsItem>
#include <QTextLayout>
//void mouseMoveEvent ( QGraphicsSceneMouseEvent * event );
private:
//void mouseMoveEvent ( QGraphicsSceneMouseEvent * event );
private:
+ int heightForWidth(int width);
+
+ int _lineHeight;
QRectF _boundingRect;
//QTextLayout _layout;
//QTextOption _textOption;
QRectF _boundingRect;
//QTextLayout _layout;
//QTextOption _textOption;
public:
enum ChatLineRole {
public:
enum ChatLineRole {
- FormatRole = MessageModel::UserRole
+ WrapListRole = MessageModel::UserRole
};
ChatLineModel(QObject *parent = 0);
};
ChatLineModel(QObject *parent = 0);
_sender.formatList = m.sender.formatList;
_contents.formatList = m.contents.formatList;
_sender.formatList = m.sender.formatList;
_contents.formatList = m.contents.formatList;
- case ChatLineModel::DisplayRole: return part->plainText;
- case ChatLineModel::FormatRole: return QVariant::fromValue<UiStyle::FormatList>(part->formatList);
+ case ChatLineModel::DisplayRole:
+ return part->plainText;
+ case ChatLineModel::FormatRole:
+ return QVariant::fromValue<UiStyle::FormatList>(part->formatList);
+ case ChatLineModel::WrapListRole:
+ if(column != ChatLineModel::ContentsColumn) return QVariant();
+ QVariantList wrapList;
+ typedef QPair<quint16, quint16> WrapPoint; // foreach can't parse templated params
+ foreach(WrapPoint pair, _wrapList) wrapList << pair.first << pair.second;
+ return wrapList;
}
return MessageModelItem::data(column, role);
}
return MessageModelItem::data(column, role);
-void ChatLineModelItem::computeWordList() {
- QList<QPair<quint16, quint16> > 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;
QTextBoundaryFinder finder(QTextBoundaryFinder::Word, _contents.plainText);
int idx;
int flistidx = -1;
} while(idx < _contents.plainText.length());
// A QVector needs less space than a QList
} 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++) {
for(int i = 0; i < wplist.count(); i++) {
- _wordList[i] = wplist.at(i);
+ _wrapList[i] = wplist.at(i);
virtual bool setData(int column, const QVariant &value, int role);
private:
virtual bool setData(int column, const QVariant &value, int role);
private:
- void computeWordList();
+ typedef QVector<QPair<quint16, quint16> > WrapList;
+
+ void computeWrapList();
struct ChatLinePart {
QString plainText;
struct ChatLinePart {
QString plainText;
};
ChatLinePart _timestamp, _sender, _contents;
};
ChatLinePart _timestamp, _sender, _contents;
- QVector<QPair<quint16, quint16> > _wordList;