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

Nepomuk-Core

  • KTp
  • Declarative
conversations-model.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 Lasath Fernando <kde@lasath.org>
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 
20 #include "conversations-model.h"
21 #include "conversation.h"
22 #include "conversation-target.h"
23 #include "messages-model.h"
24 #include "channel-delegator.h"
25 
26 #include <KDebug>
27 
28 #include <TelepathyQt/ChannelClassSpec>
29 #include <TelepathyQt/TextChannel>
30 #include <TelepathyQt/ClientRegistrar>
31 
32 static inline Tp::ChannelClassSpecList channelClassList()
33 {
34  return Tp::ChannelClassSpecList() << Tp::ChannelClassSpec::textChat();
35 }
36 
37 class ConversationsModel::ConversationsModelPrivate
38 {
39  public:
40  QList<Conversation*> conversations;
41 };
42 
43 ConversationsModel::ConversationsModel(QObject *parent) :
44  QAbstractListModel(parent),
45  Tp::AbstractClientHandler(channelClassList()),
46  d(new ConversationsModelPrivate)
47 {
48  QHash<int, QByteArray> roles;
49  roles[ConversationRole] = "conversation";
50  setRoleNames(roles);
51  connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalUnreadCountChanged()));
52  connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalUnreadCountChanged()));
53 }
54 
55 ConversationsModel::~ConversationsModel()
56 {
57  qDeleteAll(d->conversations);
58  delete d;
59 }
60 
61 QVariant ConversationsModel::data(const QModelIndex &index, int role) const
62 {
63  QVariant result;
64  if (index.isValid()) {
65  if (role == ConversationRole) {
66  result = QVariant::fromValue<Conversation*>(d->conversations[index.row()]);
67  kDebug() << "returning value " << result;
68  }
69  }
70  return result;
71 }
72 
73 int ConversationsModel::rowCount(const QModelIndex &parent) const
74 {
75  Q_UNUSED(parent);
76  return d->conversations.count();
77 }
78 
79 void ConversationsModel::handleChannels(const Tp::MethodInvocationContextPtr<> &context,
80  const Tp::AccountPtr &account,
81  const Tp::ConnectionPtr &connection,
82  const QList<Tp::ChannelPtr> &channels,
83  const QList<Tp::ChannelRequestPtr> &channelRequests,
84  const QDateTime &userActionTime,
85  const HandlerInfo &handlerInfo)
86 {
87  Q_UNUSED(connection);
88  Q_UNUSED(handlerInfo);
89 
90  bool handled = false;
91  bool shouldDelegate = false;
92 
93  //check that the channel is of type text
94  Tp::TextChannelPtr textChannel;
95  Q_FOREACH(const Tp::ChannelPtr &channel, channels) {
96  textChannel = Tp::TextChannelPtr::dynamicCast(channel);
97  if (textChannel) {
98  break;
99  }
100  }
101 
102  Q_ASSERT(textChannel);
103 
104 
105  //find the relevant channelRequest
106  Q_FOREACH(const Tp::ChannelRequestPtr channelRequest, channelRequests) {
107  kDebug() << channelRequest->hints().allHints();
108  shouldDelegate = channelRequest->hints().hint(QLatin1String("org.freedesktop.Telepathy.ChannelRequest"), QLatin1String("DelegateToPreferredHandler")).toBool();
109  }
110 
111 
112  //loop through all conversations checking for matches
113 
114  //if we are handling and we're not told to delegate it, update the text channel
115  //if we are handling but should delegate, call delegate channel
116  Q_FOREACH(Conversation *convo, d->conversations) {
117  if (convo->target()->id() == textChannel->targetId() &&
118  convo->messages()->textChannel()->targetHandleType() == textChannel->targetHandleType())
119  {
120  if (!shouldDelegate) {
121  convo->messages()->setTextChannel(textChannel);
122  } else {
123  if (convo->messages()->textChannel() == textChannel) {
124  ChannelDelegator::delegateChannel(account, textChannel, userActionTime);
125  }
126  }
127  handled = true;
128  break;
129  }
130  }
131 
132  //if we are not handling channel already and should not delegate, add the conversation
133  //if we not handling the channel but should delegate it, do nothing.
134 
135  if (!handled && !shouldDelegate) {
136  beginInsertRows(QModelIndex(), rowCount(), rowCount());
137  Conversation *newConvo = new Conversation(textChannel, account, this);
138  d->conversations.append(newConvo);
139  connect(newConvo, SIGNAL(validityChanged(bool)), SLOT(handleValidityChange(bool)));
140  connect(newConvo, SIGNAL(conversationDelegated()), SLOT(conversationDelegated()));
141  connect(newConvo->messages(), SIGNAL(unreadCountChanged(int)), SIGNAL(totalUnreadCountChanged()));
142  endInsertRows();
143  context->setFinished();
144  }
145 
146 }
147 
148 bool ConversationsModel::bypassApproval() const
149 {
150  return true;
151 }
152 
153 void ConversationsModel::startChat(const Tp::AccountPtr &account, const KTp::ContactPtr &contact)
154 {
155  Q_ASSERT(account);
156  account->ensureTextChat(contact, QDateTime::currentDateTime(),
157  QLatin1String("org.freedesktop.Telepathy.Client.KDE.TextUi.ConversationWatcher"));
158 }
159 
160 void ConversationsModel::handleValidityChange(bool valid)
161 {
162  if (!valid) {
163  removeConversation(qobject_cast<Conversation*>(QObject::sender()));
164  }
165 }
166 
167 void ConversationsModel::conversationDelegated()
168 {
169  removeConversation(qobject_cast<Conversation*>(QObject::sender()));
170 }
171 
172 void ConversationsModel::removeConversation(Conversation* conv)
173 {
174  int index = d->conversations.indexOf(conv);
175  if (index != -1) {
176  beginRemoveRows(QModelIndex(), index, index);
177  d->conversations.removeAt(index);
178  conv->deleteLater();
179  endRemoveRows();
180  } else {
181  kError() << "attempting to delete non-existent conversation";
182  }
183 }
184 
185 int ConversationsModel::nextActiveConversation(int fromRow)
186 {
187  if(d->conversations.isEmpty()) {
188  return -1;
189  }
190  Q_ASSERT(qBound(0, fromRow, d->conversations.count()-1) == fromRow);
191 
192  bool first = true; //let first be checked on the first loop
193  for(int i = fromRow; i != fromRow || first; i = (i + 1) % d->conversations.count()) {
194  if(d->conversations[i]->messages()->unreadCount() > 0) {
195  return i;
196  }
197  first = false;
198  }
199  return -1;
200 }
201 
202 int ConversationsModel::totalUnreadCount() const
203 {
204  int ret = 0;
205  Q_FOREACH(Conversation *c, d->conversations) {
206  ret += c->messages()->unreadCount();
207  }
208  return ret;
209 }
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