• Skip to content
  • Skip to link menu
  • KDE API Reference
  • KDE Home
  • Contact Us
 

Nepomuk-Core

  • KTp
  • Models
text-channel-watcher-proxy-model.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 David Edmundson <kde@davidedmundson.co.uk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "text-channel-watcher-proxy-model.h"
20 
21 #include <TelepathyQt/TextChannel>
22 #include <TelepathyQt/ChannelClassSpecList>
23 #include <TelepathyQt/MethodInvocationContext>
24 #include <TelepathyQt/Types>
25 #include <TelepathyQt/ReceivedMessage>
26 
27 #include <KTp/types.h>
28 #include <KTp/contact.h>
29 
30 
31 inline Tp::ChannelClassSpecList channelClasses() {
32  return Tp::ChannelClassSpecList() << Tp::ChannelClassSpec::textChat();
33 }
34 
35 class ChannelWatcher : public QObject, public Tp::RefCounted
36 {
37  Q_OBJECT
38 public:
39  ChannelWatcher(const QPersistentModelIndex &index, const Tp::TextChannelPtr &channel, QObject *parent=0);
40  int unreadMessageCount() const;
41  QPersistentModelIndex modelIndex() const;
42 Q_SIGNALS:
43  void messagesChanged();
44  void invalidated();
45 private:
46  QPersistentModelIndex m_index;
47  Tp::TextChannelPtr m_channel;
48 };
49 
50 typedef Tp::SharedPtr<ChannelWatcher> ChannelWatcherPtr;
51 
52 ChannelWatcher::ChannelWatcher(const QPersistentModelIndex &index, const Tp::TextChannelPtr &channel, QObject *parent):
53  QObject(parent),
54  m_index(index),
55  m_channel(channel)
56 {
57  connect(channel.data(), SIGNAL(pendingMessageRemoved(Tp::ReceivedMessage)), SIGNAL(messagesChanged()));
58  connect(channel.data(), SIGNAL(messageReceived(Tp::ReceivedMessage)), SIGNAL(messagesChanged()));
59  connect(channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)), SIGNAL(invalidated()));
60 
61  //trigger an update to the contact straight away
62  QTimer::singleShot(0, this, SIGNAL(messagesChanged()));
63 }
64 
65 QPersistentModelIndex ChannelWatcher::modelIndex() const
66 {
67  return m_index;
68 }
69 
70 int ChannelWatcher::unreadMessageCount() const
71 {
72  return m_channel->messageQueue().size();
73 }
74 
75 
76 
77 
78 namespace KTp {
79 
80 class TextChannelWatcherProxyModel::Private {
81 public:
82  QHash<KTp::ContactPtr, ChannelWatcherPtr> currentChannels;
83 };
84 
85 } //namespace
86 
87 
88 
89 
90 KTp::TextChannelWatcherProxyModel::TextChannelWatcherProxyModel(QObject *parent) :
91  QIdentityProxyModel(parent),
92  Tp::AbstractClientObserver(channelClasses(), true),
93  d(new TextChannelWatcherProxyModel::Private)
94 {
95 }
96 
97 KTp::TextChannelWatcherProxyModel::~TextChannelWatcherProxyModel()
98 {
99  delete d;
100 }
101 
102 void KTp::TextChannelWatcherProxyModel::observeChannels(const Tp::MethodInvocationContextPtr<> &context, const Tp::AccountPtr &account, const Tp::ConnectionPtr &connection, const QList<Tp::ChannelPtr> &channels, const Tp::ChannelDispatchOperationPtr &dispatchOperation, const QList<Tp::ChannelRequestPtr> &requestsSatisfied, const Tp::AbstractClientObserver::ObserverInfo &observerInfo)
103 {
104  Q_UNUSED(context)
105  Q_UNUSED(account)
106  Q_UNUSED(connection)
107  Q_UNUSED(dispatchOperation)
108  Q_UNUSED(requestsSatisfied)
109  Q_UNUSED(observerInfo)
110 
111  if (!sourceModel()) {
112  return;
113  }
114 
115  Q_FOREACH(const Tp::ChannelPtr & channel, channels) {
116  Tp::TextChannelPtr textChannel = Tp::TextChannelPtr::dynamicCast(channel);
117  if (textChannel) {
118  KTp::ContactPtr targetContact = KTp::ContactPtr::qObjectCast(textChannel->targetContact());
119 
120  //skip group chats and situations where we don't have a single contact to mark messages for
121  if (targetContact.isNull()) {
122  continue;
123  }
124 
125  //if it's not in our source model, ignore the channel
126  QModelIndexList matchedContacts = sourceModel()->match(QModelIndex(sourceModel()->index(0,0)), KTp::ContactRole, QVariant::fromValue(targetContact));
127  if (matchedContacts.size() !=1) {
128  continue;
129  }
130 
131  QPersistentModelIndex contactIndex(matchedContacts[0]);
132 
133  ChannelWatcherPtr watcher = ChannelWatcherPtr(new ChannelWatcher(contactIndex, textChannel));
134  d->currentChannels[targetContact] = watcher;
135 
136  connect(watcher.data(), SIGNAL(messagesChanged()), SLOT(onChannelMessagesChanged()));
137  }
138  }
139 }
140 
141 QVariant KTp::TextChannelWatcherProxyModel::data(const QModelIndex &proxyIndex, int role) const
142 {
143  QModelIndex sourceIndex = mapToSource(proxyIndex);
144  if (role == KTp::ContactHasTextChannelRole) {
145  KTp::ContactPtr contact = sourceIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
146  if (contact) {
147  if (d->currentChannels.contains(contact)) {
148  return true;
149  }
150  }
151  return false;
152  }
153 
154  if (role == KTp::ContactUnreadMessageCountRole) {
155  KTp::ContactPtr contact = sourceIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
156  if (contact) {
157  if (d->currentChannels.contains(contact)) {
158  return d->currentChannels[contact]->unreadMessageCount();
159  }
160  }
161  return 0;
162  }
163 
164  return sourceIndex.data(role);
165 }
166 
167 void KTp::TextChannelWatcherProxyModel::onChannelMessagesChanged()
168 {
169  ChannelWatcher* watcher = qobject_cast<ChannelWatcher*>(sender());
170  Q_ASSERT(watcher);
171  QModelIndex index = watcher->modelIndex();
172  dataChanged(index, index);
173 }
174 
175 void KTp::TextChannelWatcherProxyModel::onChannelInvalidated()
176 {
177  ChannelWatcher* watcher = qobject_cast<ChannelWatcher*>(sender());
178  Q_ASSERT(watcher);
179  QModelIndex index = watcher->modelIndex();
180  KTp::ContactPtr contact = index.data(KTp::ContactRole).value<KTp::ContactPtr>();
181 
182  d->currentChannels.remove(contact);
183  dataChanged(index, index);
184 }
185 
186 #include "text-channel-watcher-proxy-model.moc"
187 #include "moc_text-channel-watcher-proxy-model.cpp"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Fri Mar 22 2013 10:58:52 by doxygen 1.8.1.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

ktp-common-internals API Reference

Skip menu "ktp-common-internals API Reference"
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal