From: Marcus Eggenberger Date: Tue, 13 Jan 2009 14:21:24 +0000 (+0100) Subject: quassel no longer allocates an MessageItem on the heap for every message - working... X-Git-Tag: 0.4.0~226 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=86831c8857f0a729580cee547e10c9621d50c780 quassel no longer allocates an MessageItem on the heap for every message - working towards a better mem handling --- diff --git a/src/client/messagemodel.cpp b/src/client/messagemodel.cpp index 906b2c17..76943d4c 100644 --- a/src/client/messagemodel.cpp +++ b/src/client/messagemodel.cpp @@ -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(); - if(row < 0 || row >= _messageList.count() || column < 0) + if(row < 0 || row >= messageCount() || column < 0) 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(); - if(row < 0 || row >= _messageList.count()) + if(row < 0 || row >= messageCount()) return false; - if(_messageList[row]->setData(index.column(), value, role)) { + if(messageItemAt(row)->setData(index.column(), value, role)) { emit dataChanged(index, index); return true; } - 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; } @@ -111,23 +111,31 @@ void MessageModel::insertMessageGroup(const QList &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; - 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; - 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); - 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()); - dayChangeItem = createMessageModelItem(dayChangeMsg); } - delete oldItem; endRemoveRows(); start--; end--; @@ -135,13 +143,14 @@ void MessageModel::insertMessageGroup(const QList &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 - 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); @@ -150,33 +159,35 @@ void MessageModel::insertMessageGroup(const QList &msglist) { 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()); - dayChangeItem = createMessageModelItem(dayChangeMsg); } } - if(dayChangeItem) + if(dayChangeMsg.isValid()) 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); - 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); - 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 &msglist) { @@ -205,13 +216,13 @@ int MessageModel::insertMessagesGracefully(const QList &msglist) { } 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) - minId = _messageList[idx - 1]->msgId(); + minId = messageItemAt(idx - 1)->msgId(); else fastForward = true; @@ -233,8 +244,8 @@ int MessageModel::insertMessagesGracefully(const QList &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(idx >= 0 && !_messageList.isEmpty()) - dupeId = _messageList[idx]->msgId(); + if(idx >= 0 && !messagesIsEmpty()) + dupeId = messageItemAt(idx)->msgId(); } if((*iter).msgId() != dupeId) { if(!grouplist.isEmpty()) { @@ -264,8 +275,8 @@ int MessageModel::insertMessagesGracefully(const QList &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(idx >= 0 && !_messageList.isEmpty()) - dupeId = _messageList[idx]->msgId(); + if(idx >= 0 && !messagesIsEmpty()) + dupeId = messageItemAt(idx)->msgId(); } if((*iter).msgId() != dupeId) { if(!grouplist.isEmpty()) { @@ -316,41 +327,41 @@ void MessageModel::customEvent(QEvent *event) { 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) { - if(_messageList.isEmpty() || id <= _messageList.value(0)->msgId()) + if(messagesIsEmpty() || id <= messageItemAt(0)->msgId()) return 0; - if(id > _messageList.last()->msgId()) - return _messageList.count(); + + if(id > lastMessageItem()->msgId()) + return messageCount(); // 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; - if(id <= _messageList.value(pivot)->msgId()) end = pivot; + if(id <= messageItemAt(pivot)->msgId()) end = pivot; 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); - 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); @@ -363,14 +374,14 @@ void MessageModel::requestBacklog(BufferId bufferId) { 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))); - Client::backlogManager()->requestBacklog(bufferId, -1, _messageList.at(i)->msgId(), requestCount); + Client::backlogManager()->requestBacklog(bufferId, -1, messageItemAt(i)->msgId(), requestCount); return; } } @@ -386,9 +397,9 @@ void MessageModel::messagesReceived(BufferId bufferId, int count) { } 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); } @@ -398,15 +409,11 @@ void MessageModel::buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferI // ======================================== // 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 { @@ -414,11 +421,11 @@ QVariant MessageModelItem::data(int column, int role) const { return QVariant(); switch(role) { - case MessageModel::MsgIdRole: return QVariant::fromValue(_msgId); - case MessageModel::BufferIdRole: return QVariant::fromValue(_bufferId); - case MessageModel::TypeRole: return _type; - case MessageModel::FlagsRole: return (int)_flags; - case MessageModel::TimestampRole: return _timestamp; + case MessageModel::MsgIdRole: return QVariant::fromValue(msgId()); + case MessageModel::BufferIdRole: return QVariant::fromValue(bufferId()); + case MessageModel::TypeRole: return msgType(); + case MessageModel::FlagsRole: return (int)msgFlags(); + case MessageModel::TimestampRole: return timestamp(); case MessageModel::RedirectedToRole: return qVariantFromValue(_redirectedTo); default: return QVariant(); } @@ -442,20 +449,20 @@ bool MessageModelItem::lessThan(const MessageModelItem *m1, const MessageModelIt } bool MessageModelItem::operator<(const MessageModelItem &other) const { - return _msgId < other._msgId; + return msgId() < other.msgId(); } bool MessageModelItem::operator==(const MessageModelItem &other) const { - return _msgId == other._msgId; + return msgId() == other.msgId(); } 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() - << 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(); diff --git a/src/client/messagemodel.h b/src/client/messagemodel.h index 33321d53..5da8309d 100644 --- a/src/client/messagemodel.h +++ b/src/client/messagemodel.h @@ -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 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; @@ -75,7 +75,22 @@ public slots: 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 &) = 0; + virtual void removeMessageAt(int i) = 0; + virtual void removeAllMessages() = 0; + virtual Message takeMessageAt(int i) = 0; + virtual void customEvent(QEvent *event); private slots: @@ -86,7 +101,7 @@ private: int insertMessagesGracefully(const QList &); // inserts as many contiguous msgs as possible. returns numer of inserted msgs. int indexForId(MsgId); - QList _messageList; + // QList _messageList; QList _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); - 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 ×tamp() 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; @@ -123,12 +139,8 @@ public: static bool lessThan(const MessageModelItem *m1, const MessageModelItem *m2); private: - QDateTime _timestamp; - MsgId _msgId; - BufferId _bufferId; + Message _msg; BufferId _redirectedTo; - Message::Type _type; - Message::Flags _flags; }; QDebug operator<<(QDebug dbg, const MessageModelItem &msgItem); diff --git a/src/common/bufferinfo.h b/src/common/bufferinfo.h index 9ca41609..0953a10f 100644 --- a/src/common/bufferinfo.h +++ b/src/common/bufferinfo.h @@ -50,13 +50,14 @@ public: 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; } + + QString bufferName() const; inline bool operator==(const BufferInfo &other) const { return _bufferId == other._bufferId; } diff --git a/src/common/message.h b/src/common/message.h index c1b8e625..ee299c63 100644 --- a/src/common/message.h +++ b/src/common/message.h @@ -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"))); } - inline MsgId msgId() const { return _msgId; } + inline const MsgId &msgId() const { return _msgId; } 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 QDateTime timestamp() const { return _timestamp; } + inline const QDateTime ×tamp() const { return _timestamp; } inline bool isValid() const { return _msgId.isValid(); } diff --git a/src/qtui/chatlinemodel.cpp b/src/qtui/chatlinemodel.cpp index 4dd8f886..72af95c1 100644 --- a/src/qtui/chatlinemodel.cpp +++ b/src/qtui/chatlinemodel.cpp @@ -20,8 +20,6 @@ #include "chatlinemodel.h" -#include "chatlinemodelitem.h" - ChatLineModel::ChatLineModel(QObject *parent) : MessageModel(parent) { @@ -29,10 +27,22 @@ ChatLineModel::ChatLineModel(QObject *parent) qRegisterMetaTypeStreamOperators("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 &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(); diff --git a/src/qtui/chatlinemodel.h b/src/qtui/chatlinemodel.h index 77cab193..12770d20 100644 --- a/src/qtui/chatlinemodel.h +++ b/src/qtui/chatlinemodel.h @@ -23,6 +23,9 @@ #include "messagemodel.h" +#include +#include "chatlinemodelitem.h" + class ChatLineModel : public MessageModel { Q_OBJECT @@ -33,18 +36,28 @@ public: 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 WrapList; + typedef ChatLineModelItem::Word Word; + typedef ChatLineModelItem::WrapList WrapList; 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 &); + virtual inline void removeMessageAt(int i) { _messageList.removeAt(i); } + virtual inline void removeAllMessages() { _messageList.clear(); } + virtual Message takeMessageAt(int i); +private: + QList _messageList; }; QDataStream &operator<<(QDataStream &out, const ChatLineModel::WrapList); diff --git a/src/qtui/chatlinemodelitem.cpp b/src/qtui/chatlinemodelitem.cpp index 7d6e8327..681f4cf7 100644 --- a/src/qtui/chatlinemodelitem.cpp +++ b/src/qtui/chatlinemodelitem.cpp @@ -215,6 +215,12 @@ ChatLineModelItem::ChatLineModelItem(const Message &msg) { } +ChatLineModelItem::ChatLineModelItem(const ChatLineModelItem &other) + : MessageModelItem(other) +{ + _data = new ChatLineModelItemPrivate(message()); +} + ChatLineModelItem::~ChatLineModelItem() { delete _data; } diff --git a/src/qtui/chatlinemodelitem.h b/src/qtui/chatlinemodelitem.h index 8cf1fa61..d4979cdf 100644 --- a/src/qtui/chatlinemodelitem.h +++ b/src/qtui/chatlinemodelitem.h @@ -21,19 +21,27 @@ #ifndef CHATLINEMODELITEM_H_ #define CHATLINEMODELITEM_H_ -#include - -#include "chatlinemodel.h" -#include "uistyle.h" +#include "messagemodel.h" class ChatLineModelItemPrivate; class ChatLineModelItem : public MessageModelItem { public: ChatLineModelItem(const Message &); + ChatLineModelItem(const ChatLineModelItem &other); ~ChatLineModelItem(); + 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 WrapList; + private: ChatLineModelItemPrivate *_data; }; diff --git a/src/qtui/chatview.cpp b/src/qtui/chatview.cpp index a686a7a1..2a999ea1 100644 --- a/src/qtui/chatview.cpp +++ b/src/qtui/chatview.cpp @@ -19,11 +19,11 @@ ***************************************************************************/ #include +#include #include #include #include "bufferwidget.h" -#include "chatlinemodelitem.h" #include "chatscene.h" #include "chatview.h" #include "client.h" diff --git a/src/uisupport/uistyle.h b/src/uisupport/uistyle.h index 3bb1a45b..6bd68015 100644 --- a/src/uisupport/uistyle.h +++ b/src/uisupport/uistyle.h @@ -157,27 +157,26 @@ class UiStyle { }; 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);