From: Manuel Nickschas Date: Wed, 11 Jun 2008 00:06:33 +0000 (+0200) Subject: ChatLineModelItem now computes and stores wordlists X-Git-Tag: 0.3.0~183 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=bedd08ea58926e41e6ad1d0bf256a97cae97fb3c ChatLineModelItem now computes and stores wordlists Lines are split into words, and both wrap points and the width of each word are stored in the item. Computation should be very fast even though it does consider the true bounding rect for the given formats. --- diff --git a/src/client/client.cpp b/src/client/client.cpp index e532df8a..113338fa 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -448,9 +448,11 @@ void Client::recvStatusMsg(QString /*net*/, QString /*msg*/) { void Client::receiveBacklog(BufferId bufferId, const QVariantList &msgs) { //checkForHighlight(msg); + //QTime start = QTime::currentTime(); foreach(QVariant v, msgs) { _messageModel->insertMessage(v.value()); } + //qDebug() << "processed" << msgs.count() << "backlog lines in" << start.msecsTo(QTime::currentTime()); } void Client::layoutMsg() { diff --git a/src/qtui/chatlinemodelitem.cpp b/src/qtui/chatlinemodelitem.cpp index 59f7b5cc..8d15b92c 100644 --- a/src/qtui/chatlinemodelitem.cpp +++ b/src/qtui/chatlinemodelitem.cpp @@ -18,6 +18,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include +#include + #include "chatlinemodelitem.h" #include "chatlinemodel.h" #include "qtui.h" @@ -34,6 +37,7 @@ ChatLineModelItem::ChatLineModelItem(const Message &msg) : MessageModelItem(msg) _sender.formatList = m.sender.formatList; _contents.formatList = m.contents.formatList; + computeWordList(); } @@ -58,3 +62,40 @@ QVariant ChatLineModelItem::data(int column, int role) const { 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 + QTextBoundaryFinder finder(QTextBoundaryFinder::Word, _contents.plainText); + int idx; + int flistidx = -1; + int fmtend = -1; + QFontMetricsF *metrics; + QPair wp(0, 0); + do { + idx = finder.toNextBoundary(); + if(idx < 0) idx = _contents.plainText.length(); + else if(finder.boundaryReasons() != QTextBoundaryFinder::StartWord) continue; + int start = wp.first; + while(start < idx) { + if(fmtend <= start) { + flistidx++; + fmtend = _contents.formatList.count() > flistidx+1 ? _contents.formatList[flistidx+1].first + : _contents.plainText.length(); + metrics = QtUi::style()->fontMetrics(_contents.formatList[flistidx].second); + Q_ASSERT(fmtend > start); + } + int i = qMin(idx, fmtend); + wp.second += metrics->width(_contents.plainText.mid(start, i - start)); + start = i; + } + wplist.append(wp); + wp.first = idx; + } while(idx < _contents.plainText.length()); + + // A QVector needs less space than a QList + _wordList.resize(wplist.count()); + for(int i = 0; i < wplist.count(); i++) { + _wordList[i] = wplist.at(i); + } +} + diff --git a/src/qtui/chatlinemodelitem.h b/src/qtui/chatlinemodelitem.h index 9b5a4966..24fed2be 100644 --- a/src/qtui/chatlinemodelitem.h +++ b/src/qtui/chatlinemodelitem.h @@ -21,6 +21,9 @@ #ifndef CHATLINEMODELITEM_H_ #define CHATLINEMODELITEM_H_ +#include +#include + #include "messagemodel.h" #include "uistyle.h" @@ -34,13 +37,15 @@ class ChatLineModelItem : public MessageModelItem { virtual bool setData(int column, const QVariant &value, int role); private: + void computeWordList(); + struct ChatLinePart { QString plainText; UiStyle::FormatList formatList; - }; - ChatLinePart _timestamp, _sender, _contents; + + QVector > _wordList; }; #endif