quassel no longer allocates an MessageItem on the heap for every message - working...
authorMarcus Eggenberger <egs@quassel-irc.org>
Tue, 13 Jan 2009 14:21:24 +0000 (15:21 +0100)
committerMarcus Eggenberger <egs@quassel-irc.org>
Tue, 13 Jan 2009 15:35:09 +0000 (16:35 +0100)
src/client/messagemodel.cpp
src/client/messagemodel.h
src/common/bufferinfo.h
src/common/message.h
src/qtui/chatlinemodel.cpp
src/qtui/chatlinemodel.h
src/qtui/chatlinemodelitem.cpp
src/qtui/chatlinemodelitem.h
src/qtui/chatview.cpp
src/uisupport/uistyle.h

index 906b2c1..76943d4 100644 (file)
@@ -48,33 +48,33 @@ MessageModel::MessageModel(QObject *parent)
 
 QVariant MessageModel::data(const QModelIndex &index, int role) const {
   int row = index.row(); int column = index.column();
 
 QVariant MessageModel::data(const QModelIndex &index, int role) const {
   int row = index.row(); int column = index.column();
-  if(row < 0 || row >= _messageList.count() || column < 0)
+  if(row < 0 || row >= messageCount() || column < 0)
     return QVariant();
 
   if(role == ColumnTypeRole)
     return column;
 
     return QVariant();
 
   if(role == ColumnTypeRole)
     return column;
 
-  return _messageList[row]->data(index.column(), role);
+  return messageItemAt(row)->data(index.column(), role);
+  // return _messageList[row]->data(index.column(), role);
 }
 
 bool MessageModel::setData(const QModelIndex &index, const QVariant &value, int role) {
   int row = index.row();
 }
 
 bool MessageModel::setData(const QModelIndex &index, const QVariant &value, int role) {
   int row = index.row();
-  if(row < 0 || row >= _messageList.count())
+  if(row < 0 || row >= messageCount())
     return false;
 
     return false;
 
-  if(_messageList[row]->setData(index.column(), value, role)) {
+  if(messageItemAt(row)->setData(index.column(), value, role)) {
     emit dataChanged(index, index);
     return true;
   }
     emit dataChanged(index, index);
     return true;
   }
-
   return false;
 }
 
 bool MessageModel::insertMessage(const Message &msg, bool fakeMsg) {
   MsgId id = msg.msgId();
   int idx = indexForId(id);
   return false;
 }
 
 bool MessageModel::insertMessage(const Message &msg, bool fakeMsg) {
   MsgId id = msg.msgId();
   int idx = indexForId(id);
-  if(!fakeMsg && idx < _messageList.count()) { // check for duplicate
-    if(_messageList[idx]->msgId() == id)
+  if(!fakeMsg && idx < messageCount()) { // check for duplicate
+    if(messageItemAt(idx)->msgId() == id)
       return false;
   }
 
       return false;
   }
 
@@ -111,23 +111,31 @@ void MessageModel::insertMessageGroup(const QList<Message> &msglist) {
 //   Q_ASSERT(0 == last || msglist.at(0).msgId() != msglist.at(last).msgId() || msglist.at(last).type() == Message::DayChange);
   int start = indexForId(msglist.first().msgId());
   int end = start + msglist.count() - 1;
 //   Q_ASSERT(0 == last || msglist.at(0).msgId() != msglist.at(last).msgId() || msglist.at(last).type() == Message::DayChange);
   int start = indexForId(msglist.first().msgId());
   int end = start + msglist.count() - 1;
-  MessageModelItem *dayChangeItem = 0;
+  Message dayChangeMsg;
+//   MessageModelItem *dayChangeItem = 0;
   bool relocatedMsg = false;
   if(start > 0) {
     // check if the preceeding msg is a daychange message and if so if
     // we have to drop or relocate it at the end of this chunk
     int prevIdx = start - 1;
   bool relocatedMsg = false;
   if(start > 0) {
     // check if the preceeding msg is a daychange message and if so if
     // we have to drop or relocate it at the end of this chunk
     int prevIdx = start - 1;
-    if(_messageList.at(prevIdx)->msgType() == Message::DayChange
-       && _messageList.at(prevIdx)->timeStamp() > msglist.at(0).timestamp()) {
+    if(messageItemAt(prevIdx)->msgType() == Message::DayChange
+       && messageItemAt(prevIdx)->timestamp() > msglist.at(0).timestamp()) {
       beginRemoveRows(QModelIndex(), prevIdx, prevIdx);
       beginRemoveRows(QModelIndex(), prevIdx, prevIdx);
-      MessageModelItem *oldItem = _messageList.takeAt(prevIdx);
-      if(msglist.last().timestamp() < oldItem->timeStamp()) {
-       // we have to reinsert it (with changed msgId -> thus we need to recreate it)
-       Message dayChangeMsg = Message::ChangeOfDay(oldItem->timeStamp());
+//       MessageModelItem *oldItem = _messageList.takeAt(prevIdx);
+//       if(msglist.last().timestamp() < oldItem->timestamp()) {
+//     // we have to reinsert it (with changed msgId -> thus we need to recreate it)
+//     Message dayChangeMsg = Message::ChangeOfDay(oldItem->timestamp());
+//     dayChangeMsg.setMsgId(msglist.last().msgId());
+//     dayChangeItem = createMessageModelItem(dayChangeMsg);
+//       }
+//       delete oldItem;
+
+
+      dayChangeMsg = takeMessageAt(prevIdx);
+      if(msglist.last().timestamp() < dayChangeMsg.timestamp()) {
+       // we have to reinsert it with a changed msgId
        dayChangeMsg.setMsgId(msglist.last().msgId());
        dayChangeMsg.setMsgId(msglist.last().msgId());
-       dayChangeItem = createMessageModelItem(dayChangeMsg);
       }
       }
-      delete oldItem;
       endRemoveRows();
       start--;
       end--;
       endRemoveRows();
       start--;
       end--;
@@ -135,13 +143,14 @@ void MessageModel::insertMessageGroup(const QList<Message> &msglist) {
     }
   }
 
     }
   }
 
-  if(!dayChangeItem && start < _messageList.count()) {
+  if(!dayChangeMsg.isValid() && start < messageCount()) {
+    // if(!dayChangeItem && start < _messageList.count()) {
     // check if we need to insert a daychange message at the end of the this group
 
     // if this assert triggers then indexForId() would have found a spot right before a DayChangeMsg
     // this should never happen as daychange messages share the msgId with the preceeding message
     // check if we need to insert a daychange message at the end of the this group
 
     // if this assert triggers then indexForId() would have found a spot right before a DayChangeMsg
     // this should never happen as daychange messages share the msgId with the preceeding message
-    Q_ASSERT(_messageList[start]->msgType() != Message::DayChange);
-    QDateTime nextTs = _messageList[start]->timeStamp();
+    Q_ASSERT(messageItemAt(start)->msgType() != Message::DayChange);
+    QDateTime nextTs = messageItemAt(start)->timestamp();
     QDateTime prevTs = msglist.last().timestamp();
     nextTs.setTimeSpec(Qt::UTC);
     prevTs.setTimeSpec(Qt::UTC);
     QDateTime prevTs = msglist.last().timestamp();
     nextTs.setTimeSpec(Qt::UTC);
     prevTs.setTimeSpec(Qt::UTC);
@@ -150,33 +159,35 @@ void MessageModel::insertMessageGroup(const QList<Message> &msglist) {
     if(nextDay != prevDay) {
       nextTs.setTime_t(nextDay * 86400);
       nextTs.setTimeSpec(Qt::LocalTime);
     if(nextDay != prevDay) {
       nextTs.setTime_t(nextDay * 86400);
       nextTs.setTimeSpec(Qt::LocalTime);
-      Message dayChangeMsg = Message::ChangeOfDay(nextTs);
+      dayChangeMsg = Message::ChangeOfDay(nextTs);
       dayChangeMsg.setMsgId(msglist.last().msgId());
       dayChangeMsg.setMsgId(msglist.last().msgId());
-      dayChangeItem = createMessageModelItem(dayChangeMsg);
     }
   }
 
     }
   }
 
-  if(dayChangeItem)
+  if(dayChangeMsg.isValid())
     end++;
 
     end++;
 
-  Q_ASSERT(start == 0 || _messageList[start - 1]->msgId() < msglist.first().msgId());
-  Q_ASSERT(start == _messageList.count() || _messageList[start]->msgId() > msglist.last().msgId());
+  Q_ASSERT(start == 0 || messageItemAt(start - 1)->msgId() < msglist.first().msgId());
+  Q_ASSERT(start == messageCount() || messageItemAt(start)->msgId() > msglist.last().msgId());
   beginInsertRows(QModelIndex(), start, end);
   beginInsertRows(QModelIndex(), start, end);
-  int pos = start;
-  foreach(Message msg, msglist) {
-    _messageList.insert(pos, createMessageModelItem(msg));
-    pos++;
-  }
-  if(dayChangeItem) {
-    _messageList.insert(pos, dayChangeItem);
-    pos++; // needed for the following assert
-  }
+//   int pos = start;
+//   foreach(Message msg, msglist) {
+//     _messageList.insert(pos, createMessageModelItem(msg));
+//     pos++;
+//   }
+//   if(dayChangeItem) {
+//     _messageList.insert(pos, dayChangeItem);
+//     pos++; // needed for the following assert
+//   }
+  insertMessages__(start, msglist);
+  if(dayChangeMsg.isValid())
+    insertMessage__(start + msglist.count(), dayChangeMsg);
   endInsertRows();
 
 //   Q_ASSERT(start == end || _messageList.at(start)->msgId() != _messageList.at(end)->msgId() || _messageList.at(end)->msgType() == Message::DayChange);
   endInsertRows();
 
 //   Q_ASSERT(start == end || _messageList.at(start)->msgId() != _messageList.at(end)->msgId() || _messageList.at(end)->msgType() == Message::DayChange);
-  Q_ASSERT(start == 0 || _messageList[start - 1]->msgId() < _messageList[start]->msgId());
-  Q_ASSERT(end + 1 == _messageList.count() || _messageList[end]->msgId() < _messageList[end + 1]->msgId());
-  Q_ASSERT(pos - 1 == end);
+  Q_ASSERT(start == 0 || messageItemAt(start - 1)->msgId() < messageItemAt(start)->msgId());
+  Q_ASSERT(end + 1 == messageCount() || messageItemAt(end)->msgId() < messageItemAt(end + 1)->msgId());
+//   Q_ASSERT(pos - 1 == end);
 }
 
 int MessageModel::insertMessagesGracefully(const QList<Message> &msglist) {
 }
 
 int MessageModel::insertMessagesGracefully(const QList<Message> &msglist) {
@@ -205,13 +216,13 @@ int MessageModel::insertMessagesGracefully(const QList<Message> &msglist) {
   }
 
   idx = indexForId((*iter).msgId());
   }
 
   idx = indexForId((*iter).msgId());
-  if(idx < _messageList.count())
-    dupeId = _messageList[idx]->msgId();
+  if(idx < messageCount())
+    dupeId = messageItemAt(idx)->msgId();
 
   // we always compare to the previous entry...
   // if there isn't, we can fastforward to the top
   if(idx - 1 >= 0)
 
   // we always compare to the previous entry...
   // if there isn't, we can fastforward to the top
   if(idx - 1 >= 0)
-    minId = _messageList[idx - 1]->msgId();
+    minId = messageItemAt(idx - 1)->msgId();
   else
     fastForward = true;
 
   else
     fastForward = true;
 
@@ -233,8 +244,8 @@ int MessageModel::insertMessagesGracefully(const QList<Message> &msglist) {
 
       if(grouplist.isEmpty()) { // as long as we don't have a starting point, we have to update the dupeId
        idx = indexForId((*iter).msgId());
 
       if(grouplist.isEmpty()) { // as long as we don't have a starting point, we have to update the dupeId
        idx = indexForId((*iter).msgId());
-       if(idx >= 0 && !_messageList.isEmpty())
-         dupeId = _messageList[idx]->msgId();
+       if(idx >= 0 && !messagesIsEmpty())
+         dupeId = messageItemAt(idx)->msgId();
       }
       if((*iter).msgId() != dupeId) {
        if(!grouplist.isEmpty()) {
       }
       if((*iter).msgId() != dupeId) {
        if(!grouplist.isEmpty()) {
@@ -264,8 +275,8 @@ int MessageModel::insertMessagesGracefully(const QList<Message> &msglist) {
 
       if(grouplist.isEmpty()) { // as long as we don't have a starting point, we have to update the dupeId
        idx = indexForId((*iter).msgId());
 
       if(grouplist.isEmpty()) { // as long as we don't have a starting point, we have to update the dupeId
        idx = indexForId((*iter).msgId());
-       if(idx >= 0 && !_messageList.isEmpty())
-         dupeId = _messageList[idx]->msgId();
+       if(idx >= 0 && !messagesIsEmpty())
+         dupeId = messageItemAt(idx)->msgId();
       }
       if((*iter).msgId() != dupeId) {
        if(!grouplist.isEmpty()) {
       }
       if((*iter).msgId() != dupeId) {
        if(!grouplist.isEmpty()) {
@@ -316,41 +327,41 @@ void MessageModel::customEvent(QEvent *event) {
 
 void MessageModel::clear() {
   beginRemoveRows(QModelIndex(), 0, rowCount() - 1);
 
 void MessageModel::clear() {
   beginRemoveRows(QModelIndex(), 0, rowCount() - 1);
-  qDeleteAll(_messageList);
-  _messageList.clear();
+  removeAllMessages();
   endRemoveRows();
   _messagesWaiting.clear();
 }
 
 // returns index of msg with given Id or of the next message after that (i.e., the index where we'd insert this msg)
 int MessageModel::indexForId(MsgId id) {
   endRemoveRows();
   _messagesWaiting.clear();
 }
 
 // returns index of msg with given Id or of the next message after that (i.e., the index where we'd insert this msg)
 int MessageModel::indexForId(MsgId id) {
-  if(_messageList.isEmpty() || id <= _messageList.value(0)->msgId())
+  if(messagesIsEmpty() || id <= messageItemAt(0)->msgId())
     return 0;
     return 0;
-  if(id > _messageList.last()->msgId())
-    return _messageList.count();
+
+  if(id > lastMessageItem()->msgId())
+    return messageCount();
 
   // binary search
 
   // binary search
-  int start = 0; int end = _messageList.count()-1;
+  int start = 0; int end = messageCount() - 1;
   while(1) {
     if(end - start == 1)
       return end;
     int pivot = (end + start) / 2;
   while(1) {
     if(end - start == 1)
       return end;
     int pivot = (end + start) / 2;
-    if(id <= _messageList.value(pivot)->msgId()) end = pivot;
+    if(id <= messageItemAt(pivot)->msgId()) end = pivot;
     else start = pivot;
   }
 }
 
 void MessageModel::changeOfDay() {
   _dayChangeTimer.setInterval(86400000);
     else start = pivot;
   }
 }
 
 void MessageModel::changeOfDay() {
   _dayChangeTimer.setInterval(86400000);
-  if(!_messageList.isEmpty()) {
-    int idx = _messageList.count();
-    while(idx > 0 && _messageList[idx - 1]->timeStamp() > _nextDayChange) {
+  if(!messagesIsEmpty()) {
+    int idx = messageCount();
+    while(idx > 0 && messageItemAt(idx - 1)->timestamp() > _nextDayChange) {
       idx--;
     }
     beginInsertRows(QModelIndex(), idx, idx);
     Message dayChangeMsg = Message::ChangeOfDay(_nextDayChange);
       idx--;
     }
     beginInsertRows(QModelIndex(), idx, idx);
     Message dayChangeMsg = Message::ChangeOfDay(_nextDayChange);
-    dayChangeMsg.setMsgId(_messageList[idx - 1]->msgId());
-    _messageList.insert(idx, createMessageModelItem(dayChangeMsg));
+    dayChangeMsg.setMsgId(messageItemAt(idx - 1)->msgId());
+    insertMessage__(idx, dayChangeMsg);
     endInsertRows();
   }
   _nextDayChange = _nextDayChange.addSecs(86400);
     endInsertRows();
   }
   _nextDayChange = _nextDayChange.addSecs(86400);
@@ -363,14 +374,14 @@ void MessageModel::requestBacklog(BufferId bufferId) {
   BacklogSettings backlogSettings;
   int requestCount = backlogSettings.dynamicBacklogAmount();
 
   BacklogSettings backlogSettings;
   int requestCount = backlogSettings.dynamicBacklogAmount();
 
-  for(int i = 0; i < _messageList.count(); i++) {
-    if(_messageList.at(i)->bufferId() == bufferId) {
+  for(int i = 0; i < messageCount(); i++) {
+    if(messageItemAt(i)->bufferId() == bufferId) {
       _messagesWaiting[bufferId] = requestCount;
       Client::backlogManager()->emitMessagesRequested(tr("Requesting %1 messages from backlog for buffer %2:%3")
                                                      .arg(requestCount)
                                                      .arg(Client::networkModel()->networkName(bufferId))
                                                      .arg(Client::networkModel()->bufferName(bufferId)));
       _messagesWaiting[bufferId] = requestCount;
       Client::backlogManager()->emitMessagesRequested(tr("Requesting %1 messages from backlog for buffer %2:%3")
                                                      .arg(requestCount)
                                                      .arg(Client::networkModel()->networkName(bufferId))
                                                      .arg(Client::networkModel()->bufferName(bufferId)));
-      Client::backlogManager()->requestBacklog(bufferId, -1, _messageList.at(i)->msgId(), requestCount);
+      Client::backlogManager()->requestBacklog(bufferId, -1, messageItemAt(i)->msgId(), requestCount);
       return;
     }
   }
       return;
     }
   }
@@ -386,9 +397,9 @@ void MessageModel::messagesReceived(BufferId bufferId, int count) {
 }
 
 void MessageModel::buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferId2) {
 }
 
 void MessageModel::buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferId2) {
-  for(int i = 0; i < _messageList.count(); i++) {
-    if(_messageList[i]->bufferId() == bufferId2) {
-      _messageList[i]->setBufferId(bufferId1);
+  for(int i = 0; i < messageCount(); i++) {
+    if(messageItemAt(i)->bufferId() == bufferId2) {
+      messageItemAt(i)->setBufferId(bufferId1);
       QModelIndex idx = index(i, 0);
       emit dataChanged(idx, idx);
     }
       QModelIndex idx = index(i, 0);
       emit dataChanged(idx, idx);
     }
@@ -398,15 +409,11 @@ void MessageModel::buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferI
 // ========================================
 //  MessageModelItem
 // ========================================
 // ========================================
 //  MessageModelItem
 // ========================================
-MessageModelItem::MessageModelItem(const Message &msg) :
-  _timestamp(msg.timestamp()),
-  _msgId(msg.msgId()),
-  _bufferId(msg.bufferInfo().bufferId()),
-  _type(msg.type()),
-  _flags(msg.flags())
+MessageModelItem::MessageModelItem(const Message &msg)
+  : _msg(msg)
 {
 {
-  if(!msg.sender().contains('!'))
-    _flags |= Message::ServerMsg;
+  if(!_msg.sender().contains('!'))
+    _msg.setFlags(_msg.flags() |= Message::ServerMsg);
 }
 
 QVariant MessageModelItem::data(int column, int role) const {
 }
 
 QVariant MessageModelItem::data(int column, int role) const {
@@ -414,11 +421,11 @@ QVariant MessageModelItem::data(int column, int role) const {
     return QVariant();
 
   switch(role) {
     return QVariant();
 
   switch(role) {
-  case MessageModel::MsgIdRole: return QVariant::fromValue<MsgId>(_msgId);
-  case MessageModel::BufferIdRole: return QVariant::fromValue<BufferId>(_bufferId);
-  case MessageModel::TypeRole: return _type;
-  case MessageModel::FlagsRole: return (int)_flags;
-  case MessageModel::TimestampRole: return _timestamp;
+  case MessageModel::MsgIdRole: return QVariant::fromValue<MsgId>(msgId());
+  case MessageModel::BufferIdRole: return QVariant::fromValue<BufferId>(bufferId());
+  case MessageModel::TypeRole: return msgType();
+  case MessageModel::FlagsRole: return (int)msgFlags();
+  case MessageModel::TimestampRole: return timestamp();
   case MessageModel::RedirectedToRole: return qVariantFromValue<BufferId>(_redirectedTo);
   default: return QVariant();
   }
   case MessageModel::RedirectedToRole: return qVariantFromValue<BufferId>(_redirectedTo);
   default: return QVariant();
   }
@@ -442,20 +449,20 @@ bool MessageModelItem::lessThan(const MessageModelItem *m1, const MessageModelIt
 }
 
 bool MessageModelItem::operator<(const MessageModelItem &other) const {
 }
 
 bool MessageModelItem::operator<(const MessageModelItem &other) const {
-  return _msgId < other._msgId;
+  return msgId() < other.msgId();
 }
 
 bool MessageModelItem::operator==(const MessageModelItem &other) const {
 }
 
 bool MessageModelItem::operator==(const MessageModelItem &other) const {
-  return _msgId == other._msgId;
+  return msgId() == other.msgId();
 }
 
 bool MessageModelItem::operator>(const MessageModelItem &other) const {
 }
 
 bool MessageModelItem::operator>(const MessageModelItem &other) const {
-  return _msgId > other._msgId;
+  return msgId() > other.msgId();
 }
 
 QDebug operator<<(QDebug dbg, const MessageModelItem &msgItem) {
   dbg.nospace() << qPrintable(QString("MessageModelItem(MsgId:")) << msgItem.msgId()
 }
 
 QDebug operator<<(QDebug dbg, const MessageModelItem &msgItem) {
   dbg.nospace() << qPrintable(QString("MessageModelItem(MsgId:")) << msgItem.msgId()
-               << qPrintable(QString(",")) << msgItem.timeStamp()
+               << qPrintable(QString(",")) << msgItem.timestamp()
                << qPrintable(QString(", Type:")) << msgItem.msgType()
                << qPrintable(QString(", Flags:")) << msgItem.msgFlags() << qPrintable(QString(")"))
                << msgItem.data(1, Qt::DisplayRole).toString() << ":" << msgItem.data(2, Qt::DisplayRole).toString();
                << qPrintable(QString(", Type:")) << msgItem.msgType()
                << qPrintable(QString(", Flags:")) << msgItem.msgFlags() << qPrintable(QString(")"))
                << msgItem.data(1, Qt::DisplayRole).toString() << ":" << msgItem.data(2, Qt::DisplayRole).toString();
index 33321d5..5da8309 100644 (file)
@@ -56,7 +56,7 @@ public:
 
   inline QModelIndex index(int row, int column, const QModelIndex &/*parent*/ = QModelIndex()) const { return createIndex(row, column); }
   inline QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
 
   inline QModelIndex index(int row, int column, const QModelIndex &/*parent*/ = QModelIndex()) const { return createIndex(row, column); }
   inline QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
-  inline int rowCount(const QModelIndex &parent = QModelIndex()) const { return parent.isValid() ? 0 : _messageList.count(); }
+  inline int rowCount(const QModelIndex &parent = QModelIndex()) const { return parent.isValid() ? 0 : messageCount(); }
   inline int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 3; }
 
   virtual QVariant data(const QModelIndex &index, int role) const;
   inline int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 3; }
 
   virtual QVariant data(const QModelIndex &index, int role) const;
@@ -75,7 +75,22 @@ public slots:
   void buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferId2);
 
 protected:
   void buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferId2);
 
 protected:
-  virtual MessageModelItem *createMessageModelItem(const Message &) = 0;
+//   virtual MessageModelItem *createMessageModelItem(const Message &) = 0;
+
+  virtual int messageCount() const = 0;
+  virtual bool messagesIsEmpty() const = 0;
+  virtual const MessageModelItem *messageItemAt(int i) const = 0;
+  virtual MessageModelItem *messageItemAt(int i) = 0;
+  virtual const MessageModelItem *firstMessageItem() const= 0;
+  virtual MessageModelItem *firstMessageItem() = 0;
+  virtual const MessageModelItem *lastMessageItem() const= 0;
+  virtual MessageModelItem *lastMessageItem() = 0;
+  virtual void insertMessage__(int pos, const Message &) = 0;
+  virtual void insertMessages__(int pos, const QList<Message> &) = 0;
+  virtual void removeMessageAt(int i) = 0;
+  virtual void removeAllMessages() = 0;
+  virtual Message takeMessageAt(int i) = 0;
+
   virtual void customEvent(QEvent *event);
 
 private slots:
   virtual void customEvent(QEvent *event);
 
 private slots:
@@ -86,7 +101,7 @@ private:
   int insertMessagesGracefully(const QList<Message> &); // inserts as many contiguous msgs as possible. returns numer of inserted msgs.
   int indexForId(MsgId);
 
   int insertMessagesGracefully(const QList<Message> &); // inserts as many contiguous msgs as possible. returns numer of inserted msgs.
   int indexForId(MsgId);
 
-  QList<MessageModelItem *> _messageList;
+  //  QList<MessageModelItem *> _messageList;
   QList<Message> _messageBuffer;
   QTimer _dayChangeTimer;
   QDateTime _nextDayChange;
   QList<Message> _messageBuffer;
   QTimer _dayChangeTimer;
   QDateTime _nextDayChange;
@@ -109,13 +124,14 @@ public:
   virtual QVariant data(int column, int role) const;
   virtual bool setData(int column, const QVariant &value, int role);
 
   virtual QVariant data(int column, int role) const;
   virtual bool setData(int column, const QVariant &value, int role);
 
-  inline const QDateTime &timeStamp() const { return _timestamp; }
-  inline MsgId msgId() const { return _msgId; }
-  inline BufferId bufferId() const { return _bufferId; }
-  inline void setBufferId(BufferId bufferId) { _bufferId = bufferId; }
-  inline Message::Type msgType() const { return _type; }
-  inline Message::Flags msgFlags() const { return _flags; }
-  
+  inline const Message &message() const { return _msg; }
+  inline const QDateTime &timestamp() const { return _msg.timestamp(); }
+  inline const MsgId &msgId() const { return _msg.msgId(); }
+  inline const BufferId &bufferId() const { return _msg.bufferId(); }
+  inline void setBufferId(BufferId bufferId) { _msg.setBufferId(bufferId); }
+  inline Message::Type msgType() const { return _msg.type(); }
+  inline Message::Flags msgFlags() const { return _msg.flags(); }
+
   // For sorting
   bool operator<(const MessageModelItem &) const;
   bool operator==(const MessageModelItem &) const;
   // For sorting
   bool operator<(const MessageModelItem &) const;
   bool operator==(const MessageModelItem &) const;
@@ -123,12 +139,8 @@ public:
   static bool lessThan(const MessageModelItem *m1, const MessageModelItem *m2);
 
 private:
   static bool lessThan(const MessageModelItem *m1, const MessageModelItem *m2);
 
 private:
-  QDateTime _timestamp;
-  MsgId _msgId;
-  BufferId _bufferId;
+  Message _msg;
   BufferId _redirectedTo;
   BufferId _redirectedTo;
-  Message::Type _type;
-  Message::Flags _flags;
 };
 
 QDebug operator<<(QDebug dbg, const MessageModelItem &msgItem);
 };
 
 QDebug operator<<(QDebug dbg, const MessageModelItem &msgItem);
index 9ca4160..0953a10 100644 (file)
@@ -50,13 +50,14 @@ public:
   static BufferInfo fakeStatusBuffer(NetworkId networkId);
 
   inline bool isValid() const { return _bufferId != 0; }
   static BufferInfo fakeStatusBuffer(NetworkId networkId);
 
   inline bool isValid() const { return _bufferId != 0; }
-  inline BufferId bufferId() const { return _bufferId; }
-  inline NetworkId networkId() const { return _netid; }
-  inline Type type() const { return _type; }
-  inline uint groupId() const { return _groupId; }
-  QString bufferName() const;
-  
+  inline const BufferId &bufferId() const { return _bufferId; }
+  inline void setBufferId(BufferId id) { _bufferId = id; }
+  inline const NetworkId &networkId() const { return _netid; }
+  inline const Type &type() const { return _type; }
+  inline const uint &groupId() const { return _groupId; }
   void setGroupId(uint gid) { _groupId = gid; }
   void setGroupId(uint gid) { _groupId = gid; }
+
+  QString bufferName() const;
   
   inline bool operator==(const BufferInfo &other) const { return _bufferId == other._bufferId; }
 
   
   inline bool operator==(const BufferInfo &other) const { return _bufferId == other._bufferId; }
 
index c1b8e62..ee299c6 100644 (file)
@@ -66,16 +66,18 @@ public:
           const QString &contents = "", const QString &sender = "", Flags flags = None);
 
   inline static Message ChangeOfDay(const QDateTime &day) { return Message(day, BufferInfo(), DayChange, tr("Day changed to %1").arg(day.toString("dddd MMMM d yyyy"))); }
           const QString &contents = "", const QString &sender = "", Flags flags = None);
 
   inline static Message ChangeOfDay(const QDateTime &day) { return Message(day, BufferInfo(), DayChange, tr("Day changed to %1").arg(day.toString("dddd MMMM d yyyy"))); }
-  inline MsgId msgId() const { return _msgId; }
+  inline const MsgId &msgId() const { return _msgId; }
   inline void setMsgId(MsgId id) { _msgId = id; }
 
   inline void setMsgId(MsgId id) { _msgId = id; }
 
-  inline BufferInfo bufferInfo() const { return _bufferInfo; }
-  inline QString contents() const { return _contents; }
-  inline QString sender() const { return _sender; }
+  inline const BufferInfo &bufferInfo() const { return _bufferInfo; }
+  inline const BufferId &bufferId() const { return _bufferInfo.bufferId(); }
+  inline void setBufferId(BufferId id) { _bufferInfo.setBufferId(id); }
+  inline const QString &contents() const { return _contents; }
+  inline const QString &sender() const { return _sender; }
   inline Type type() const { return _type; }
   inline Flags flags() const { return _flags; }
   inline void setFlags(Flags flags) { _flags = flags; }
   inline Type type() const { return _type; }
   inline Flags flags() const { return _flags; }
   inline void setFlags(Flags flags) { _flags = flags; }
-  inline QDateTime timestamp() const { return _timestamp; }
+  inline const QDateTime &timestamp() const { return _timestamp; }
 
   inline bool isValid() const { return _msgId.isValid(); }
 
 
   inline bool isValid() const { return _msgId.isValid(); }
 
index 4dd8f88..72af95c 100644 (file)
@@ -20,8 +20,6 @@
 
 #include "chatlinemodel.h"
 
 
 #include "chatlinemodel.h"
 
-#include "chatlinemodelitem.h"
-
 ChatLineModel::ChatLineModel(QObject *parent)
   : MessageModel(parent)
 {
 ChatLineModel::ChatLineModel(QObject *parent)
   : MessageModel(parent)
 {
@@ -29,10 +27,22 @@ ChatLineModel::ChatLineModel(QObject *parent)
   qRegisterMetaTypeStreamOperators<WrapList>("ChatLineModel::WrapList");
 }
 
   qRegisterMetaTypeStreamOperators<WrapList>("ChatLineModel::WrapList");
 }
 
-MessageModelItem *ChatLineModel::createMessageModelItem(const Message &msg) {
-  return new ChatLineModelItem(msg);
+// MessageModelItem *ChatLineModel::createMessageModelItem(const Message &msg) {
+//   return new ChatLineModelItem(msg);
+// }
+
+void ChatLineModel::insertMessages__(int pos, const QList<Message> &messages) {
+  for(int i = 0; i < messages.count(); i++) {
+    _messageList.insert(pos, ChatLineModelItem(messages[i]));
+    pos++;
+  }
 }
 
 }
 
+Message ChatLineModel::takeMessageAt(int i) {
+  Message msg = _messageList[i].message();
+  _messageList.removeAt(i);
+  return msg;
+}
 
 QDataStream &operator<<(QDataStream &out, const ChatLineModel::WrapList wplist) {
   out << wplist.count();
 
 QDataStream &operator<<(QDataStream &out, const ChatLineModel::WrapList wplist) {
   out << wplist.count();
index 77cab19..12770d2 100644 (file)
@@ -23,6 +23,9 @@
 
 #include "messagemodel.h"
 
 
 #include "messagemodel.h"
 
+#include <QList>
+#include "chatlinemodelitem.h"
+
 class ChatLineModel : public MessageModel {
   Q_OBJECT
 
 class ChatLineModel : public MessageModel {
   Q_OBJECT
 
@@ -33,18 +36,28 @@ public:
 
   ChatLineModel(QObject *parent = 0);
 
 
   ChatLineModel(QObject *parent = 0);
 
-  /// Used to store information about words to be used for wrapping
-  struct Word {
-    quint16 start;
-    qreal endX;
-    qreal width;
-    qreal trailing;
-  };
-  typedef QVector<Word> WrapList;
+  typedef ChatLineModelItem::Word Word;
+  typedef ChatLineModelItem::WrapList WrapList;
 
 protected:
 
 protected:
-  virtual MessageModelItem *createMessageModelItem(const Message &);
+//   virtual MessageModelItem *createMessageModelItem(const Message &);
+
+  virtual inline int messageCount() const { return _messageList.count(); }
+  virtual inline bool messagesIsEmpty() const { return _messageList.isEmpty(); }
+  virtual inline const MessageModelItem *messageItemAt(int i) const { return &_messageList[i]; }
+  virtual inline MessageModelItem *messageItemAt(int i) { return &_messageList[i]; }
+  virtual inline const MessageModelItem *firstMessageItem() const { return &_messageList.first(); }
+  virtual inline MessageModelItem *firstMessageItem() { return &_messageList.first(); }
+  virtual inline const MessageModelItem *lastMessageItem() const { return &_messageList.last(); }
+  virtual inline MessageModelItem *lastMessageItem() { return &_messageList.last(); }
+  virtual inline void insertMessage__(int pos, const Message &msg) { _messageList.insert(pos, ChatLineModelItem(msg)); }
+  virtual void insertMessages__(int pos, const QList<Message> &);
+  virtual inline void removeMessageAt(int i) { _messageList.removeAt(i); }
+  virtual inline void removeAllMessages() { _messageList.clear(); }
+  virtual Message takeMessageAt(int i);
 
 
+private:
+  QList<ChatLineModelItem> _messageList;
 };
 
 QDataStream &operator<<(QDataStream &out, const ChatLineModel::WrapList);
 };
 
 QDataStream &operator<<(QDataStream &out, const ChatLineModel::WrapList);
index 7d6e832..681f4cf 100644 (file)
@@ -215,6 +215,12 @@ ChatLineModelItem::ChatLineModelItem(const Message &msg)
 {
 }
 
 {
 }
 
+ChatLineModelItem::ChatLineModelItem(const ChatLineModelItem &other)
+  : MessageModelItem(other)
+{
+  _data = new ChatLineModelItemPrivate(message());
+}
+
 ChatLineModelItem::~ChatLineModelItem() {
   delete _data;
 }
 ChatLineModelItem::~ChatLineModelItem() {
   delete _data;
 }
index 8cf1fa6..d4979cd 100644 (file)
 #ifndef CHATLINEMODELITEM_H_
 #define CHATLINEMODELITEM_H_
 
 #ifndef CHATLINEMODELITEM_H_
 #define CHATLINEMODELITEM_H_
 
-#include <QVector>
-
-#include "chatlinemodel.h"
-#include "uistyle.h"
+#include "messagemodel.h"
 
 class ChatLineModelItemPrivate;
 
 class ChatLineModelItem : public MessageModelItem {
 public:
   ChatLineModelItem(const Message &);
 
 class ChatLineModelItemPrivate;
 
 class ChatLineModelItem : public MessageModelItem {
 public:
   ChatLineModelItem(const Message &);
+  ChatLineModelItem(const ChatLineModelItem &other);
   ~ChatLineModelItem();
   ~ChatLineModelItem();
+
   virtual QVariant data(int column, int role) const;
 
   virtual QVariant data(int column, int role) const;
 
+  /// Used to store information about words to be used for wrapping
+  struct Word {
+    quint16 start;
+    qreal endX;
+    qreal width;
+    qreal trailing;
+  };
+  typedef QVector<Word> WrapList;
+
 private:
   ChatLineModelItemPrivate *_data;
 };
 private:
   ChatLineModelItemPrivate *_data;
 };
index a686a7a..2a999ea 100644 (file)
  ***************************************************************************/
 
 #include <QGraphicsTextItem>
  ***************************************************************************/
 
 #include <QGraphicsTextItem>
+#include <QKeyEvent>
 #include <QMenu>
 #include <QScrollBar>
 
 #include "bufferwidget.h"
 #include <QMenu>
 #include <QScrollBar>
 
 #include "bufferwidget.h"
-#include "chatlinemodelitem.h"
 #include "chatscene.h"
 #include "chatview.h"
 #include "client.h"
 #include "chatscene.h"
 #include "chatview.h"
 #include "client.h"
index 3bb1a45..6bd6801 100644 (file)
@@ -157,27 +157,26 @@ class UiStyle {
 };
 
 class UiStyle::StyledMessage {
 };
 
 class UiStyle::StyledMessage {
-
-  public:
-    explicit StyledMessage(const Message &, UiStyle *style);
-
-    QDateTime timestamp() const;
-    QString decoratedTimestamp() const;
-    QString sender() const;             //!< Nickname (no decorations) for Plain and Notice, empty else
-    QString decoratedSender() const;
-    QString contents() const;
-
-    FormatType timestampFormat() const;
-    FormatType senderFormat() const;
-    FormatList contentsFormatList() const;
-
-    inline Message::Type type() const { return _msgType; }
-
-  private:
-    StyledString _contents;
-    QDateTime _timestamp;
-    QString _sender;
-    Message::Type _msgType;
+public:
+  explicit StyledMessage(const Message &, UiStyle *style);
+
+  QDateTime timestamp() const;
+  QString decoratedTimestamp() const;
+  QString sender() const;             //!< Nickname (no decorations) for Plain and Notice, empty else
+  QString decoratedSender() const;
+  QString contents() const;
+
+  FormatType timestampFormat() const;
+  FormatType senderFormat() const;
+  FormatList contentsFormatList() const;
+
+  inline Message::Type type() const { return _msgType; }
+
+private:
+  StyledString _contents;
+  QDateTime _timestamp;
+  QString _sender;
+  Message::Type _msgType;
 };
 
 QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList);
 };
 
 QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList);