Changeset View
Changeset View
Standalone View
Standalone View
smsapp/conversationmodel.cpp
Show All 33 Lines | 31 | { | |||
---|---|---|---|---|---|
34 | roles.insert(DateRole, "date"); | 34 | roles.insert(DateRole, "date"); | ||
35 | setItemRoleNames(roles); | 35 | setItemRoleNames(roles); | ||
36 | } | 36 | } | ||
37 | 37 | | |||
38 | ConversationModel::~ConversationModel() | 38 | ConversationModel::~ConversationModel() | ||
39 | { | 39 | { | ||
40 | } | 40 | } | ||
41 | 41 | | |||
42 | QString ConversationModel::threadId() const | 42 | qint32 ConversationModel::threadId() const | ||
43 | { | 43 | { | ||
44 | return m_threadId; | 44 | return m_threadId; | ||
45 | } | 45 | } | ||
46 | 46 | | |||
47 | void ConversationModel::setThreadId(const QString &threadId) | 47 | void ConversationModel::setThreadId(const qint32& threadId) | ||
48 | { | 48 | { | ||
49 | if (m_threadId == threadId) | 49 | if (m_threadId == threadId) | ||
50 | return; | 50 | return; | ||
51 | 51 | | |||
52 | m_threadId = threadId; | 52 | m_threadId = threadId; | ||
53 | clear(); | 53 | clear(); | ||
54 | if (!threadId.isEmpty()) { | 54 | if (!(threadId == INVALID_THREAD_ID)) { | ||
55 | m_conversationsInterface->requestConversation(threadId, 0, 10); | 55 | requestMoreMessages(); | ||
56 | } | 56 | } | ||
57 | } | 57 | } | ||
58 | 58 | | |||
59 | void ConversationModel::setDeviceId(const QString& deviceId) | 59 | void ConversationModel::setDeviceId(const QString& deviceId) | ||
60 | { | 60 | { | ||
61 | if (deviceId == m_deviceId) | 61 | if (deviceId == m_deviceId) | ||
62 | return; | 62 | return; | ||
63 | 63 | | |||
64 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) << "setDeviceId" << "of" << this; | 64 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) << "setDeviceId" << "of" << this; | ||
65 | if (m_conversationsInterface) { | 65 | if (m_conversationsInterface) { | ||
66 | disconnect(m_conversationsInterface, SIGNAL(conversationMessageReceived(QVariantMap, int)), this, SLOT(createRowFromMessage(QVariantMap, int))); | | |||
67 | disconnect(m_conversationsInterface, SIGNAL(conversationUpdated(QVariantMap)), this, SLOT(handleConversationUpdate(QVariantMap))); | 66 | disconnect(m_conversationsInterface, SIGNAL(conversationUpdated(QVariantMap)), this, SLOT(handleConversationUpdate(QVariantMap))); | ||
68 | delete m_conversationsInterface; | 67 | delete m_conversationsInterface; | ||
69 | } | 68 | } | ||
70 | 69 | | |||
71 | m_deviceId = deviceId; | 70 | m_deviceId = deviceId; | ||
72 | 71 | | |||
73 | m_conversationsInterface = new DeviceConversationsDbusInterface(deviceId, this); | 72 | m_conversationsInterface = new DeviceConversationsDbusInterface(deviceId, this); | ||
74 | connect(m_conversationsInterface, SIGNAL(conversationMessageReceived(QVariantMap,int)), this, SLOT(createRowFromMessage(QVariantMap,int))); | | |||
75 | connect(m_conversationsInterface, SIGNAL(conversationUpdated(QVariantMap)), this, SLOT(handleConversationUpdate(QVariantMap))); | 73 | connect(m_conversationsInterface, SIGNAL(conversationUpdated(QVariantMap)), this, SLOT(handleConversationUpdate(QVariantMap))); | ||
76 | } | 74 | } | ||
77 | 75 | | |||
78 | void ConversationModel::sendReplyToConversation(const QString& message) | 76 | void ConversationModel::sendReplyToConversation(const QString& message) | ||
79 | { | 77 | { | ||
80 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) << "Trying to send" << message << "to conversation with ID" << m_threadId; | 78 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) << "Trying to send" << message << "to conversation with ID" << m_threadId; | ||
81 | m_conversationsInterface->replyToConversation(m_threadId, message); | 79 | m_conversationsInterface->replyToConversation(m_threadId, message); | ||
82 | } | 80 | } | ||
83 | 81 | | |||
82 | void ConversationModel::requestMoreMessages(const quint32& howMany) | ||||
83 | { | ||||
84 | if (m_threadId == INVALID_THREAD_ID) { | ||||
85 | return; | ||||
86 | } | ||||
87 | const auto& numMessages = rowCount(); | ||||
88 | m_conversationsInterface->requestConversation(m_threadId, numMessages, numMessages + howMany); | ||||
89 | } | ||||
90 | | ||||
84 | void ConversationModel::createRowFromMessage(const QVariantMap& msg, int pos) | 91 | void ConversationModel::createRowFromMessage(const QVariantMap& msg, int pos) | ||
85 | { | 92 | { | ||
86 | const ConversationMessage message(msg); | 93 | const ConversationMessage message(msg); | ||
87 | 94 | | |||
88 | if (!(message.threadID() == m_threadId.toInt())) { | 95 | if (!(message.threadID() == m_threadId)) { | ||
89 | // Because of the asynchronous nature of the current implementation of this model, if the | 96 | // Because of the asynchronous nature of the current implementation of this model, if the | ||
90 | // user clicks quickly between threads or for some other reason a message comes when we're | 97 | // user clicks quickly between threads or for some other reason a message comes when we're | ||
91 | // not expecting it, we should not display it in the wrong place | 98 | // not expecting it, we should not display it in the wrong place | ||
92 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) | 99 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) | ||
93 | << "Got a message for a thread" << message.threadID() | 100 | << "Got a message for a thread" << message.threadID() | ||
94 | << "but we are currently viewing" << m_threadId | 101 | << "but we are currently viewing" << m_threadId | ||
95 | << "Discarding."; | 102 | << "Discarding."; | ||
96 | return; | 103 | return; | ||
97 | } | 104 | } | ||
105 | | ||||
106 | if (knownMessageIDs.contains(message.uID())) { | ||||
107 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) | ||||
108 | << "Ignoring duplicate message with ID" << message.uID(); | ||||
109 | return; | ||||
110 | } | ||||
111 | | ||||
98 | auto item = new QStandardItem; | 112 | auto item = new QStandardItem; | ||
99 | item->setText(message.body()); | 113 | item->setText(message.body()); | ||
100 | item->setData(message.type() == ConversationMessage::MessageTypeSent, FromMeRole); | 114 | item->setData(message.type() == ConversationMessage::MessageTypeSent, FromMeRole); | ||
101 | item->setData(message.date(), DateRole); | 115 | item->setData(message.date(), DateRole); | ||
102 | insertRow(pos, item); | 116 | insertRow(pos, item); | ||
117 | knownMessageIDs.insert(message.uID()); | ||||
103 | } | 118 | } | ||
104 | 119 | | |||
105 | void ConversationModel::handleConversationUpdate(const QVariantMap& msg) | 120 | void ConversationModel::handleConversationUpdate(const QVariantMap& msg) | ||
106 | { | 121 | { | ||
107 | const ConversationMessage message(msg); | 122 | const ConversationMessage message(msg); | ||
108 | 123 | | |||
109 | if (!(message.threadID() == m_threadId.toInt())) { | 124 | if (!(message.threadID() == m_threadId)) { | ||
110 | // If a conversation which we are not currently viewing was updated, discard the information | 125 | // If a conversation which we are not currently viewing was updated, discard the information | ||
111 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) | 126 | qCDebug(KDECONNECT_SMS_CONVERSATION_MODEL) | ||
112 | << "Saw update for thread" << message.threadID() | 127 | << "Saw update for thread" << message.threadID() | ||
113 | << "but we are currently viewing" << m_threadId; | 128 | << "but we are currently viewing" << m_threadId; | ||
114 | return; | 129 | return; | ||
115 | } | 130 | } | ||
116 | 131 | | |||
117 | createRowFromMessage(msg, 0); | 132 | createRowFromMessage(msg, 0); | ||
118 | } | 133 | } |