ChatLineModelItem now computes and stores wordlists
authorManuel Nickschas <sputnick@quassel-irc.org>
Wed, 11 Jun 2008 00:06:33 +0000 (02:06 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sat, 2 Aug 2008 13:17:09 +0000 (15:17 +0200)
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.

src/client/client.cpp
src/qtui/chatlinemodelitem.cpp
src/qtui/chatlinemodelitem.h

index e532df8..113338f 100644 (file)
@@ -448,9 +448,11 @@ void Client::recvStatusMsg(QString /*net*/, QString /*msg*/) {
 
 void Client::receiveBacklog(BufferId bufferId, const QVariantList &msgs) {
   //checkForHighlight(msg);
 
 void Client::receiveBacklog(BufferId bufferId, const QVariantList &msgs) {
   //checkForHighlight(msg);
+  //QTime start = QTime::currentTime();
   foreach(QVariant v, msgs) {
     _messageModel->insertMessage(v.value<Message>());
   }
   foreach(QVariant v, msgs) {
     _messageModel->insertMessage(v.value<Message>());
   }
+  //qDebug() << "processed" << msgs.count() << "backlog lines in" << start.msecsTo(QTime::currentTime());
 }
 
 void Client::layoutMsg() {
 }
 
 void Client::layoutMsg() {
index 59f7b5c..8d15b92 100644 (file)
@@ -18,6 +18,9 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+#include <QFontMetrics>
+#include <QTextBoundaryFinder>
+
 #include "chatlinemodelitem.h"
 #include "chatlinemodel.h"
 #include "qtui.h"
 #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;
 
   _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;
 }
 bool ChatLineModelItem::setData(int column, const QVariant &value, int role) {
   return false;
 }
+
+void ChatLineModelItem::computeWordList() {
+  QList<QPair<quint16, quint16> > 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<quint16, quint16> 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);
+  }
+}
+
index 9b5a496..24fed2b 100644 (file)
@@ -21,6 +21,9 @@
 #ifndef CHATLINEMODELITEM_H_
 #define CHATLINEMODELITEM_H_
 
 #ifndef CHATLINEMODELITEM_H_
 #define CHATLINEMODELITEM_H_
 
+#include <QVector>
+#include <QPair>
+
 #include "messagemodel.h"
 #include "uistyle.h"
 
 #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:
     virtual bool setData(int column, const QVariant &value, int role);
 
   private:
+    void computeWordList();
+
     struct ChatLinePart {
       QString plainText;
       UiStyle::FormatList formatList;
     struct ChatLinePart {
       QString plainText;
       UiStyle::FormatList formatList;
-
     };
     };
-
     ChatLinePart _timestamp, _sender, _contents;
     ChatLinePart _timestamp, _sender, _contents;
+
+    QVector<QPair<quint16, quint16> > _wordList;
 };
 
 #endif
 };
 
 #endif