Merge lp:~phablet-team/telephony-service/add-participants-model into lp:telephony-service/staging
- add-participants-model
- Merge into staging
Proposed by
Tiago Salem Herrmann
Status: | Merged |
---|---|
Approved by: | Gustavo Pichorim Boiko |
Approved revision: | 1250 |
Merged at revision: | 1247 |
Proposed branch: | lp:~phablet-team/telephony-service/add-participants-model |
Merge into: | lp:telephony-service/staging |
Prerequisite: | lp:~phablet-team/telephony-service/multiple_performance_improvements1 |
Diff against target: |
595 lines (+387/-12) 9 files modified
Ubuntu/Telephony/CMakeLists.txt (+1/-0) Ubuntu/Telephony/components.cpp (+2/-0) Ubuntu/Telephony/participantsmodel.cpp (+233/-0) Ubuntu/Telephony/participantsmodel.h (+92/-0) handler/texthandler.cpp (+6/-0) libtelephonyservice/chatentry.cpp (+21/-8) libtelephonyservice/chatentry.h (+8/-1) libtelephonyservice/participant.cpp (+13/-2) libtelephonyservice/participant.h (+11/-1) |
To merge this branch: | bzr merge lp:~phablet-team/telephony-service/add-participants-model |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gustavo Pichorim Boiko (community) | Approve | ||
Review via email: mp+317390@code.launchpad.net |
Commit message
Add ParticipantsModel
Description of the change
Add ParticipantsModel
To post a comment you must log in.
- 1241. By Tiago Salem Herrmann
-
Add missing files
- 1242. By Tiago Salem Herrmann
-
add missing cpp file
- 1243. By Tiago Salem Herrmann
-
add more props to participants
- 1244. By Tiago Salem Herrmann
-
include all participants
- 1245. By Tiago Salem Herrmann
-
change string comparison method
- 1246. By Tiago Salem Herrmann
-
fallback to threadId if no participant is provided
- 1247. By Tiago Salem Herrmann
-
merge parent
- 1248. By Tiago Salem Herrmann
-
Fix sorting
- 1249. By Tiago Salem Herrmann
-
merge parent branch
- 1250. By Tiago Salem Herrmann
-
use enums instead of uints and disconnect old instances of ChatEntry from the model
Revision history for this message
Tiago Salem Herrmann (tiagosh) wrote : | # |
done
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote : | # |
Looks good now, thanks!
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Ubuntu/Telephony/CMakeLists.txt' |
2 | --- Ubuntu/Telephony/CMakeLists.txt 2016-07-05 03:34:11 +0000 |
3 | +++ Ubuntu/Telephony/CMakeLists.txt 2017-03-22 16:46:15 +0000 |
4 | @@ -2,6 +2,7 @@ |
5 | |
6 | set(plugin_SRCS |
7 | presencerequest.cpp |
8 | + participantsmodel.cpp |
9 | components.cpp |
10 | ) |
11 | |
12 | |
13 | === modified file 'Ubuntu/Telephony/components.cpp' |
14 | --- Ubuntu/Telephony/components.cpp 2016-11-23 19:28:18 +0000 |
15 | +++ Ubuntu/Telephony/components.cpp 2017-03-22 16:46:15 +0000 |
16 | @@ -39,6 +39,7 @@ |
17 | #include "accountentry.h" |
18 | #include "accountlist.h" |
19 | #include "audiooutput.h" |
20 | +#include "participantsmodel.h" |
21 | |
22 | #include <QQmlEngine> |
23 | #include <qqml.h> |
24 | @@ -87,5 +88,6 @@ |
25 | qmlRegisterType<ContactWatcher>(uri, 0, 1, "ContactWatcher"); |
26 | qmlRegisterType<Participant>(uri, 0, 1, "Participant"); |
27 | qmlRegisterType<PresenceRequest>(uri, 0, 1, "PresenceRequest"); |
28 | + qmlRegisterType<ParticipantsModel>(uri, 0, 1, "ParticipantsModel"); |
29 | qmlRegisterType<PhoneUtils>(uri, 0, 1, "PhoneUtils"); |
30 | } |
31 | |
32 | === added file 'Ubuntu/Telephony/participantsmodel.cpp' |
33 | --- Ubuntu/Telephony/participantsmodel.cpp 1970-01-01 00:00:00 +0000 |
34 | +++ Ubuntu/Telephony/participantsmodel.cpp 2017-03-22 16:46:15 +0000 |
35 | @@ -0,0 +1,233 @@ |
36 | +/* |
37 | + * Copyright (C) 2013-2017 Canonical, Ltd. |
38 | + * |
39 | + * Authors: |
40 | + * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com> |
41 | + * Tiago Salem Herrmann <tiago.herrmann@canonical.com> |
42 | + * |
43 | + * This file is part of telephony-service. |
44 | + * |
45 | + * telephony-service is free software; you can redistribute it and/or modify |
46 | + * it under the terms of the GNU General Public License as published by |
47 | + * the Free Software Foundation; version 3. |
48 | + * |
49 | + * telephony-service is distributed in the hope that it will be useful, |
50 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
51 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
52 | + * GNU General Public License for more details. |
53 | + * |
54 | + * You should have received a copy of the GNU General Public License |
55 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
56 | + */ |
57 | + |
58 | +#include "participantsmodel.h" |
59 | +#include <participant.h> |
60 | +#include <QDebug> |
61 | + |
62 | +Q_DECLARE_METATYPE(Participant) |
63 | + |
64 | +ParticipantsModel::ParticipantsModel(QObject *parent) : |
65 | + QAbstractListModel(parent), mWaitingForQml(false), mCanFetchMore(true) |
66 | +{ |
67 | + qRegisterMetaType<Participant>(); |
68 | + mRoles[AliasRole] = "alias"; |
69 | + mRoles[IdentifierRole] = "identifier"; |
70 | + mRoles[RolesRole] = "roles"; |
71 | + mRoles[StateRole] = "state"; |
72 | + |
73 | + connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged())); |
74 | + connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged())); |
75 | + connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged())); |
76 | +} |
77 | + |
78 | +bool ParticipantsModel::canFetchMore(const QModelIndex &parent) const |
79 | +{ |
80 | + return !mParticipantsCache.isEmpty(); |
81 | +} |
82 | + |
83 | +ParticipantsModel::~ParticipantsModel() |
84 | +{ |
85 | +} |
86 | + |
87 | +void ParticipantsModel::fetchMore(const QModelIndex &parent) |
88 | +{ |
89 | + if (parent.isValid() ) { |
90 | + return; |
91 | + } |
92 | + |
93 | + int max = 14; |
94 | + while (max >= 0 && !mParticipantsCache.isEmpty()) { |
95 | + addParticipant(mParticipantsCache.takeFirst()); |
96 | + max--; |
97 | + } |
98 | + |
99 | + if (mParticipantsCache.isEmpty()) { |
100 | + mCanFetchMore = false; |
101 | + Q_EMIT canFetchMoreChanged(); |
102 | + } |
103 | +} |
104 | + |
105 | +int ParticipantsModel::rowCount(const QModelIndex &parent) const |
106 | +{ |
107 | + if (parent.isValid()) { |
108 | + return 0; |
109 | + } |
110 | + |
111 | + return mParticipants.count(); |
112 | +} |
113 | + |
114 | +QHash<int, QByteArray> ParticipantsModel::roleNames() const |
115 | +{ |
116 | + return mRoles; |
117 | +} |
118 | + |
119 | +void ParticipantsModel::addParticipantCache(Participant *participant) |
120 | +{ |
121 | + int pos = positionForItem(participant->identifier(), true); |
122 | + mParticipantsCache.insert(pos, participant); |
123 | +} |
124 | + |
125 | +void ParticipantsModel::addParticipant(Participant *participant) |
126 | +{ |
127 | + int pos = positionForItem(participant->identifier()); |
128 | + beginInsertRows(QModelIndex(), pos, pos); |
129 | + mParticipants.insert(pos, participant); |
130 | + endInsertRows(); |
131 | +} |
132 | + |
133 | +void ParticipantsModel::removeParticipant(Participant *participant) |
134 | +{ |
135 | + int pos = mParticipants.indexOf(participant); |
136 | + if (pos >= 0) { |
137 | + beginRemoveRows(QModelIndex(), pos, pos); |
138 | + mParticipants.removeAt(pos); |
139 | + endRemoveRows(); |
140 | + } |
141 | + pos = mParticipantsCache.indexOf(participant); |
142 | + if (pos >= 0) { |
143 | + mParticipantsCache.removeAt(pos); |
144 | + } |
145 | +} |
146 | + |
147 | +QVariant ParticipantsModel::data(const QModelIndex &index, int role) const |
148 | +{ |
149 | + if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) { |
150 | + return QVariant(); |
151 | + } |
152 | + switch (role) { |
153 | + case IdentifierRole: |
154 | + return mParticipants[index.row()]->identifier(); |
155 | + break; |
156 | + case AliasRole: |
157 | + return mParticipants[index.row()]->alias(); |
158 | + break; |
159 | + case StateRole: |
160 | + return 0; |
161 | + break; |
162 | + case RolesRole: |
163 | + return mParticipants[index.row()]->roles(); |
164 | + break; |
165 | + } |
166 | + return QVariant(); |
167 | +} |
168 | + |
169 | +bool ParticipantsModel::lessThan(const QString &left, const QString &right) const |
170 | +{ |
171 | + // this method will push participant with names starting with non-letter |
172 | + // characters to the end of the list |
173 | + if (left.isEmpty() || right.isEmpty()) { |
174 | + return false; |
175 | + } |
176 | + if (left.at(0).isLetter() && right.at(0).isLetter()) { |
177 | + return left.localeAwareCompare(right) < 0; |
178 | + } |
179 | + if (!left.at(0).isLetter() && right.at(0).isLetter()) { |
180 | + return false; |
181 | + } |
182 | + if (left.at(0).isLetter() && !right.at(0).isLetter()) { |
183 | + return true; |
184 | + } |
185 | + |
186 | + return false; |
187 | +} |
188 | + |
189 | +int ParticipantsModel::positionForItem(const QString &item, bool cache) const |
190 | +{ |
191 | + // do a binary search for the item position on the list |
192 | + int lowerBound = 0; |
193 | + int upperBound = cache ? mParticipantsCache.count() - 1 : rowCount() - 1; |
194 | + if (upperBound < 0) { |
195 | + return 0; |
196 | + } |
197 | + |
198 | + while (true) { |
199 | + int pos = (upperBound + lowerBound) / 2; |
200 | + const QString posItem = cache ? mParticipantsCache[pos]->identifier() : index(pos).data(IdentifierRole).toString(); |
201 | + if (lowerBound == pos) { |
202 | + if (lessThan(item, posItem)) { |
203 | + return pos; |
204 | + } |
205 | + } |
206 | + if (lessThan(posItem, item)) { |
207 | + lowerBound = pos + 1; // its in the upper |
208 | + if (lowerBound > upperBound) { |
209 | + return pos += 1; |
210 | + } |
211 | + } else if (lowerBound > upperBound) { |
212 | + return pos; |
213 | + } else { |
214 | + upperBound = pos - 1; // its in the lower |
215 | + } |
216 | + } |
217 | +} |
218 | + |
219 | +void ParticipantsModel::classBegin() |
220 | +{ |
221 | + mWaitingForQml = true; |
222 | +} |
223 | + |
224 | +void ParticipantsModel::componentComplete() |
225 | +{ |
226 | + mWaitingForQml = false; |
227 | +} |
228 | + |
229 | +QVariant ParticipantsModel::get(int row) const |
230 | +{ |
231 | + QVariantMap data; |
232 | + QModelIndex idx = index(row, 0); |
233 | + if (idx.isValid()) { |
234 | + QHash<int, QByteArray> roles = roleNames(); |
235 | + Q_FOREACH(int role, roles.keys()) { |
236 | + data.insert(roles[role], idx.data(role)); |
237 | + } |
238 | + } |
239 | + |
240 | + return data; |
241 | +} |
242 | + |
243 | +ChatEntry* ParticipantsModel::chatEntry() const |
244 | +{ |
245 | + return mChatEntry; |
246 | +} |
247 | + |
248 | +void ParticipantsModel::setChatEntry(ChatEntry *entry) |
249 | +{ |
250 | + if (mChatEntry == entry) { |
251 | + return; |
252 | + } |
253 | + ChatEntry *previousChatEntry = mChatEntry; |
254 | + mChatEntry = entry; |
255 | + if (!entry) { |
256 | + return; |
257 | + } |
258 | + previousChatEntry->disconnect(this); |
259 | + connect(mChatEntry, SIGNAL(participantAdded(Participant *)), SLOT(addParticipant(Participant *))); |
260 | + connect(mChatEntry, SIGNAL(participantRemoved(Participant *)), SLOT(removeParticipant(Participant *))); |
261 | + Q_FOREACH(Participant *participant, mChatEntry->allParticipants()) { |
262 | + addParticipantCache(participant); |
263 | + } |
264 | + fetchMore(); |
265 | + mCanFetchMore = !mParticipantsCache.isEmpty(); |
266 | + Q_EMIT canFetchMoreChanged(); |
267 | + Q_EMIT chatEntryChanged(); |
268 | +} |
269 | |
270 | === added file 'Ubuntu/Telephony/participantsmodel.h' |
271 | --- Ubuntu/Telephony/participantsmodel.h 1970-01-01 00:00:00 +0000 |
272 | +++ Ubuntu/Telephony/participantsmodel.h 2017-03-22 16:46:15 +0000 |
273 | @@ -0,0 +1,92 @@ |
274 | +/* |
275 | + * Copyright (C) 2013-2017 Canonical, Ltd. |
276 | + * |
277 | + * Authors: |
278 | + * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com> |
279 | + * Tiago Salem Herrmann <tiago.herrmann@canonical.com> |
280 | + * |
281 | + * This file is part of telephony-service. |
282 | + * |
283 | + * telephony-service is free software; you can redistribute it and/or modify |
284 | + * it under the terms of the GNU General Public License as published by |
285 | + * the Free Software Foundation; version 3. |
286 | + * |
287 | + * telephony-service is distributed in the hope that it will be useful, |
288 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
289 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
290 | + * GNU General Public License for more details. |
291 | + * |
292 | + * You should have received a copy of the GNU General Public License |
293 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
294 | + */ |
295 | + |
296 | +#ifndef PARTICIPANTSMODEL_H |
297 | +#define PARTICIPANTSMODEL_H |
298 | + |
299 | +#include "chatentry.h" |
300 | +#include <QAbstractListModel> |
301 | +#include <QStringList> |
302 | +#include <QQmlParserStatus> |
303 | +#include <QQmlListProperty> |
304 | + |
305 | +class Participant; |
306 | + |
307 | +class ParticipantsModel : public QAbstractListModel, public QQmlParserStatus |
308 | +{ |
309 | + Q_OBJECT |
310 | + Q_INTERFACES(QQmlParserStatus) |
311 | + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) |
312 | + Q_PROPERTY(bool canFetchMore READ canFetchMore NOTIFY canFetchMoreChanged) |
313 | + Q_PROPERTY(ChatEntry* chatEntry READ chatEntry WRITE setChatEntry NOTIFY chatEntryChanged) |
314 | + Q_ENUMS(Role) |
315 | + |
316 | +public: |
317 | + enum Role { |
318 | + IdentifierRole = Qt::UserRole, |
319 | + AliasRole, |
320 | + RolesRole, |
321 | + StateRole |
322 | + }; |
323 | + |
324 | + explicit ParticipantsModel(QObject *parent = 0); |
325 | + ~ParticipantsModel(); |
326 | + |
327 | + Q_INVOKABLE virtual bool canFetchMore(const QModelIndex &parent = QModelIndex()) const; |
328 | + Q_INVOKABLE virtual void fetchMore(const QModelIndex &parent = QModelIndex()); |
329 | + virtual QHash<int, QByteArray> roleNames() const; |
330 | + virtual QVariant data(const QModelIndex &index, int role) const; |
331 | + int rowCount(const QModelIndex &parent = QModelIndex()) const; |
332 | + |
333 | + Q_INVOKABLE virtual QVariant get(int row) const; |
334 | + |
335 | + Q_INVOKABLE void setChatEntry(ChatEntry *entry); |
336 | + ChatEntry* chatEntry() const; |
337 | + |
338 | + void addParticipantCache(Participant *participant); |
339 | + |
340 | + void classBegin(); |
341 | + void componentComplete(); |
342 | + |
343 | +private Q_SLOTS: |
344 | + void addParticipant(Participant *participant); |
345 | + void removeParticipant(Participant *participant); |
346 | + |
347 | +Q_SIGNALS: |
348 | + void countChanged(); |
349 | + void canFetchMoreChanged(); |
350 | + void chatEntryChanged(); |
351 | + |
352 | +protected: |
353 | + bool lessThan(const QString &left, const QString &right) const; |
354 | + int positionForItem(const QString &item, bool cache = false) const; |
355 | + |
356 | +private: |
357 | + QHash<int, QByteArray> mRoles; |
358 | + QList<Participant*> mParticipants; |
359 | + bool mWaitingForQml; |
360 | + bool mCanFetchMore; |
361 | + ChatEntry *mChatEntry; |
362 | + QList<Participant*> mParticipantsCache; |
363 | +}; |
364 | + |
365 | +#endif // PARTICIPANTSMODEL_H |
366 | |
367 | === modified file 'handler/texthandler.cpp' |
368 | --- handler/texthandler.cpp 2017-03-22 16:46:14 +0000 |
369 | +++ handler/texthandler.cpp 2017-03-22 16:46:15 +0000 |
370 | @@ -168,8 +168,14 @@ |
371 | if (chatType == Tp::HandleTypeNone && targetIds.size() == 1) { |
372 | chatType = Tp::HandleTypeContact; |
373 | } |
374 | + |
375 | QString roomId = properties["threadId"].toString(); |
376 | |
377 | + // try to use the threadId as participantId if empty |
378 | + if (chatType == Tp::HandleTypeContact && targetIds.isEmpty()) { |
379 | + targetIds << roomId; |
380 | + } |
381 | + |
382 | Q_FOREACH(const Tp::TextChannelPtr &channel, mChannels) { |
383 | int count = 0; |
384 | AccountEntry *channelAccount = TelepathyHelper::instance()->accountForConnection(channel->connection()); |
385 | |
386 | === modified file 'libtelephonyservice/chatentry.cpp' |
387 | --- libtelephonyservice/chatentry.cpp 2017-03-22 16:46:14 +0000 |
388 | +++ libtelephonyservice/chatentry.cpp 2017-03-22 16:46:15 +0000 |
389 | @@ -141,15 +141,18 @@ |
390 | updateParticipants(mParticipants, |
391 | groupMembersAdded, |
392 | groupMembersRemoved, |
393 | - account); |
394 | + account, |
395 | + Participant::ParticipantStateRegular); |
396 | updateParticipants(mLocalPendingParticipants, |
397 | groupLocalPendingMembersAdded, |
398 | groupMembersRemoved + groupMembersAdded, // if contacts move to the main list, remove from the pending one |
399 | - account); |
400 | + account, |
401 | + Participant::ParticipantStateRemotePending); |
402 | updateParticipants(mRemotePendingParticipants, |
403 | groupRemotePendingMembersAdded, |
404 | groupMembersRemoved + groupMembersAdded, // if contacts move to the main list, remove from the pending one |
405 | - account); |
406 | + account, |
407 | + Participant::ParticipantStateLocalPending); |
408 | |
409 | // generate the list of participant IDs again |
410 | mParticipantIds.clear(); |
411 | @@ -265,6 +268,11 @@ |
412 | return mAutoRequest; |
413 | } |
414 | |
415 | +QList<Participant*> ChatEntry::allParticipants() const |
416 | +{ |
417 | + return mParticipants + mLocalPendingParticipants + mRemotePendingParticipants; |
418 | +} |
419 | + |
420 | bool ChatEntry::canUpdateConfiguration() const |
421 | { |
422 | return mCanUpdateConfiguration; |
423 | @@ -575,9 +583,6 @@ |
424 | |
425 | // FIXME: check how to handle multiple channels in a better way, |
426 | // for now, use the info from the last available channel |
427 | - Q_FOREACH(Participant *participant, mParticipants) { |
428 | - participant->deleteLater(); |
429 | - } |
430 | clearParticipants(); |
431 | |
432 | onGroupMembersChanged(channel->groupContacts(false), |
433 | @@ -669,26 +674,31 @@ |
434 | void ChatEntry::clearParticipants() |
435 | { |
436 | Q_FOREACH(Participant *participant, mParticipants) { |
437 | + Q_EMIT participantRemoved(participant); |
438 | participant->deleteLater(); |
439 | } |
440 | Q_FOREACH(Participant *participant, mLocalPendingParticipants) { |
441 | + Q_EMIT participantRemoved(participant); |
442 | participant->deleteLater(); |
443 | } |
444 | Q_FOREACH(Participant *participant, mRemotePendingParticipants) { |
445 | + Q_EMIT participantRemoved(participant); |
446 | participant->deleteLater(); |
447 | } |
448 | mParticipants.clear(); |
449 | mLocalPendingParticipants.clear(); |
450 | mRemotePendingParticipants.clear(); |
451 | + mRolesMap.clear(); |
452 | mSelfContactRoles = 0; |
453 | } |
454 | |
455 | -void ChatEntry::updateParticipants(QList<Participant *> &list, const Tp::Contacts &added, const Tp::Contacts &removed, AccountEntry *account) |
456 | +void ChatEntry::updateParticipants(QList<Participant *> &list, const Tp::Contacts &added, const Tp::Contacts &removed, AccountEntry *account, Participant::ParticipantState pending) |
457 | { |
458 | // first look for removed members |
459 | Q_FOREACH(Tp::ContactPtr contact, removed) { |
460 | Q_FOREACH(Participant *participant, list) { |
461 | if (account->compareIds(contact->id(), participant->identifier())) { |
462 | + Q_EMIT participantRemoved(participant); |
463 | participant->deleteLater(); |
464 | list.removeOne(participant); |
465 | break; |
466 | @@ -703,7 +713,9 @@ |
467 | // FIXME: check for duplicates? |
468 | Q_FOREACH(Tp::ContactPtr contact, added) { |
469 | uint handle = contact->handle().at(0); |
470 | - list << new Participant(contact->id(), mRolesMap[handle], handle, this); |
471 | + Participant* participant = new Participant(contact->id(), mRolesMap[handle], handle, QString(), pending, this); |
472 | + Q_EMIT participantAdded(participant); |
473 | + list << participant; |
474 | } |
475 | } |
476 | |
477 | @@ -794,6 +806,7 @@ |
478 | rolesInterface->disconnect(this); |
479 | rolesInterface = 0; |
480 | } |
481 | + clearParticipants(); |
482 | Q_EMIT activeChanged(); |
483 | Q_EMIT groupFlagsChanged(); |
484 | Q_EMIT selfContactRolesChanged(); |
485 | |
486 | === modified file 'libtelephonyservice/chatentry.h' |
487 | --- libtelephonyservice/chatentry.h 2017-03-22 16:46:14 +0000 |
488 | +++ libtelephonyservice/chatentry.h 2017-03-22 16:46:15 +0000 |
489 | @@ -25,8 +25,10 @@ |
490 | |
491 | #include <QObject> |
492 | #include <QQmlParserStatus> |
493 | +#include <QQmlListProperty> |
494 | #include <TelepathyQt/TextChannel> |
495 | #include "rolesinterface.h" |
496 | +#include "participant.h" |
497 | |
498 | class AccountEntry; |
499 | class Participant; |
500 | @@ -146,6 +148,8 @@ |
501 | void classBegin(); |
502 | void componentComplete(); |
503 | |
504 | + QList<Participant*> allParticipants() const; |
505 | + |
506 | public Q_SLOTS: |
507 | // FIXME: void or return something? |
508 | void sendMessage(const QString &accountId, const QString &message, const QVariant &attachments = QVariant(), const QVariantMap &properties = QVariantMap()); |
509 | @@ -165,7 +169,7 @@ |
510 | QVariantMap generateProperties() const; |
511 | |
512 | void clearParticipants(); |
513 | - void updateParticipants(QList<Participant*> &list, const Tp::Contacts &added, const Tp::Contacts &removed, AccountEntry *account); |
514 | + void updateParticipants(QList<Participant*> &list, const Tp::Contacts &added, const Tp::Contacts &removed, AccountEntry *account, Participant::ParticipantState = Participant::ParticipantStateRegular); |
515 | |
516 | private Q_SLOTS: |
517 | void onTextChannelAvailable(const Tp::TextChannelPtr &channel); |
518 | @@ -207,6 +211,9 @@ |
519 | void chatReady(); |
520 | void startChatFailed(); |
521 | |
522 | + void participantAdded(Participant *participant); |
523 | + void participantRemoved(Participant *participant); |
524 | + |
525 | private: |
526 | QList<Tp::TextChannelPtr> mChannels; |
527 | QStringList mParticipantIds; |
528 | |
529 | === modified file 'libtelephonyservice/participant.cpp' |
530 | --- libtelephonyservice/participant.cpp 2016-09-26 20:38:38 +0000 |
531 | +++ libtelephonyservice/participant.cpp 2017-03-22 16:46:15 +0000 |
532 | @@ -22,8 +22,8 @@ |
533 | |
534 | #include "participant.h" |
535 | |
536 | -Participant::Participant(const QString &identifier, uint roles, uint handle, QObject *parent) |
537 | -: ContactWatcher(parent), mRoles(roles), mHandle(handle) |
538 | +Participant::Participant(const QString &identifier, uint roles, uint handle, const QString &avatar, uint state, QObject *parent) |
539 | +: ContactWatcher(parent), mRoles(roles), mHandle(handle), mAvatar(avatar), mState(state) |
540 | { |
541 | classBegin(); |
542 | setIdentifier(identifier); |
543 | @@ -61,3 +61,14 @@ |
544 | { |
545 | return mHandle; |
546 | } |
547 | + |
548 | +uint Participant::state() const |
549 | +{ |
550 | + return mState; |
551 | +} |
552 | + |
553 | +QString Participant::avatar() const |
554 | +{ |
555 | + return mAvatar; |
556 | +} |
557 | + |
558 | |
559 | === modified file 'libtelephonyservice/participant.h' |
560 | --- libtelephonyservice/participant.h 2016-09-26 20:38:38 +0000 |
561 | +++ libtelephonyservice/participant.h 2017-03-22 16:46:15 +0000 |
562 | @@ -29,8 +29,14 @@ |
563 | { |
564 | Q_OBJECT |
565 | Q_PROPERTY(uint roles READ roles NOTIFY rolesChanged) |
566 | + Q_ENUMS(ParticipantState) |
567 | public: |
568 | - explicit Participant(const QString &identifier, uint roles, uint handle, QObject *parent = 0); |
569 | + enum ParticipantState { |
570 | + ParticipantStateRegular = 0, |
571 | + ParticipantStateRemotePending = 1, |
572 | + ParticipantStateLocalPending = 2, |
573 | + }; |
574 | + explicit Participant(const QString &identifier, uint roles, uint handle, const QString &avatar = QString(), uint state = 0, QObject *parent = 0); |
575 | explicit Participant(QObject *parent = 0); |
576 | explicit Participant(const Participant &other); |
577 | ~Participant(); |
578 | @@ -38,6 +44,8 @@ |
579 | void setRoles(uint roles); |
580 | uint roles() const; |
581 | uint handle() const; |
582 | + QString avatar() const; |
583 | + uint state() const; |
584 | |
585 | Q_SIGNAL |
586 | void rolesChanged(); |
587 | @@ -45,6 +53,8 @@ |
588 | private: |
589 | uint mRoles; |
590 | uint mHandle; |
591 | + QString mAvatar; |
592 | + uint mState; |
593 | }; |
594 | |
595 | #endif // PARTICIPANT_H |
Some things need to be addressed, but in general it looks good.