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

Nepomuk-Core

  • KTp
  • Widgets
join-chat-room-dialog.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of telepathy-contactslist-prototype
3  *
4  * Copyright (C) 2011 Francesco Nwokeka <francesco.nwokeka@gmail.com>
5  * Copyright (C) 2012 Dominik Cermak <d.cermak@arcor.de>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "join-chat-room-dialog.h"
23 #include "ui_join-chat-room-dialog.h"
24 
25 #include <KTp/Models/rooms-model.h>
26 
27 #include <KConfig>
28 #include <KDebug>
29 #include <KInputDialog>
30 #include <KMessageBox>
31 #include <KNotification>
32 #include <KPushButton>
33 #include <KCompletionBox>
34 
35 #include <TelepathyQt/AccountSet>
36 #include <TelepathyQt/AccountCapabilityFilter>
37 #include <TelepathyQt/AccountManager>
38 #include <TelepathyQt/AccountPropertyFilter>
39 #include <TelepathyQt/AndFilter>
40 #include <TelepathyQt/ChannelTypeRoomListInterface>
41 #include <TelepathyQt/PendingChannel>
42 #include <TelepathyQt/PendingReady>
43 #include <TelepathyQt/RequestableChannelClassSpec>
44 #include <TelepathyQt/RoomListChannel>
45 
46 #include <QSortFilterProxyModel>
47 
48 KTp::JoinChatRoomDialog::JoinChatRoomDialog(Tp::AccountManagerPtr accountManager, QWidget* parent)
49  : KDialog(parent, Qt::Dialog)
50  , ui(new Ui::JoinChatRoomDialog)
51  , m_model(new RoomsModel(this))
52  , m_favoritesModel(new FavoriteRoomsModel(this))
53  , m_favoritesProxyModel(new QSortFilterProxyModel(this))
54  , m_recentComp(new KCompletion)
55 {
56  QWidget *joinChatRoomDialog = new QWidget(this);
57  ui->setupUi(joinChatRoomDialog);
58  setMainWidget(joinChatRoomDialog);
59  setWindowIcon(KIcon(QLatin1String("telepathy-kde")));
60 
61  // config
62  KSharedConfigPtr commonConfig = KSharedConfig::openConfig(QLatin1String("ktelepathyrc"));
63  m_favoriteRoomsGroup = commonConfig->group(QLatin1String("FavoriteRooms"));
64  m_recentRoomsGroup = commonConfig->group(QLatin1String("RecentChatRooms"));
65 
66  Q_FOREACH (const QString &key, m_recentRoomsGroup.keyList()) {
67  if (!m_recentRoomsGroup.readEntry(key, QStringList()).isEmpty()) {
68  m_recentRooms.insert(key, m_recentRoomsGroup.readEntry(key, QStringList()));
69  }
70  }
71 
72  loadFavoriteRooms();
73 
74  // disable OK button on start
75  button(Ok)->setEnabled(false);
76 
77  //set icons
78  ui->addFavoritePushButton->setIcon(KIcon(QLatin1String("list-add")));
79  ui->removeFavoritePushButton->setIcon(KIcon(QLatin1String("list-remove")));
80  ui->removeRecentPushButton->setIcon(KIcon(QLatin1String("list-remove")));
81  ui->clearRecentPushButton->setIcon(KIcon(QLatin1String("edit-clear-list")));
82 
83  Tp::AccountPropertyFilterPtr isOnlineFilter = Tp::AccountPropertyFilter::create();
84  isOnlineFilter->addProperty(QLatin1String("online"), true);
85 
86  Tp::AccountCapabilityFilterPtr capabilityFilter = Tp::AccountCapabilityFilter::create(
87  Tp::RequestableChannelClassSpecList() << Tp::RequestableChannelClassSpec::conferenceTextChatroom());
88 
89  Tp::AccountFilterPtr filter = Tp::AndFilter<Tp::Account>::create((QList<Tp::AccountFilterConstPtr>() <<
90  isOnlineFilter <<
91  capabilityFilter));
92 
93  ui->comboBox->setAccountSet(accountManager->filterAccounts(filter));
94 
95  // apply the filter after populating
96  onAccountSelectionChanged(ui->comboBox->currentIndex());
97 
98  // favoritesTab
99  m_favoritesProxyModel->setSourceModel(m_favoritesModel);
100  m_favoritesProxyModel->setFilterKeyColumn(FavoriteRoomsModel::AccountIdentifierColumn);
101  m_favoritesProxyModel->setDynamicSortFilter(true);
102 
103  ui->listView->setModel(m_favoritesProxyModel);
104  ui->listView->setModelColumn(FavoriteRoomsModel::NameColumn);
105 
106  // recentTab
107  m_recentComp->setCompletionMode(KGlobalSettings::CompletionPopup);
108  m_recentComp->setIgnoreCase(true);
109 
110  ui->lineEdit->setCompletionObject(m_recentComp);
111  ui->lineEdit->setAutoDeleteCompletionObject(true);
112 
113  // queryTab
114  if (ui->comboBox->count() > 0) {
115  ui->queryPushButton->setEnabled(true);
116  }
117 
118  QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
119  proxyModel->setSourceModel(m_model);
120  proxyModel->setSortLocaleAware(true);
121  proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
122  proxyModel->setFilterKeyColumn(RoomsModel::NameColumn);
123  proxyModel->setDynamicSortFilter(true);
124 
125  ui->treeView->setModel(proxyModel);
126  ui->treeView->header()->setResizeMode(QHeaderView::ResizeToContents);
127  ui->treeView->sortByColumn(RoomsModel::NameColumn, Qt::AscendingOrder);
128 
129  // connects
130  connect(ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
131  connect(ui->listView, SIGNAL(clicked(QModelIndex)), this, SLOT(onFavoriteRoomClicked(QModelIndex)));
132  connect(ui->addFavoritePushButton, SIGNAL(clicked(bool)), this, SLOT(addFavorite()));
133  connect(ui->removeFavoritePushButton, SIGNAL(clicked(bool)), this, SLOT(removeFavorite()));
134  connect(ui->recentListWidget, SIGNAL(currentTextChanged(QString)), ui->lineEdit, SLOT(setText(QString)));
135  connect(ui->recentListWidget, SIGNAL(currentTextChanged(QString)), this, SLOT(onRecentRoomClicked()));
136  connect(ui->removeRecentPushButton, SIGNAL(clicked(bool)), this , SLOT(removeRecentRoom()));
137  connect(ui->clearRecentPushButton, SIGNAL(clicked(bool)), this, SLOT(clearRecentRooms()));
138  connect(ui->queryPushButton, SIGNAL(clicked(bool)), this, SLOT(getRoomList()));
139  connect(ui->stopPushButton, SIGNAL(clicked(bool)), this, SLOT(stopListing()));
140  connect(ui->treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onRoomClicked(QModelIndex)));
141  connect(ui->filterBar, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterFixedString(QString)));
142  connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onAccountSelectionChanged(int)));
143  connect(button(Ok), SIGNAL(clicked(bool)), this, SLOT(addRecentRoom()));
144 }
145 
146 KTp::JoinChatRoomDialog::~JoinChatRoomDialog()
147 {
148  delete ui;
149 }
150 
151 Tp::AccountPtr KTp::JoinChatRoomDialog::selectedAccount() const
152 {
153  return ui->comboBox->currentAccount();
154 }
155 
156 void KTp::JoinChatRoomDialog::onAccountSelectionChanged(int newIndex)
157 {
158  // Show only favorites associated with the selected account
159  Q_UNUSED(newIndex)
160 
161  if (!ui->comboBox->currentAccount()) {
162  return;
163  }
164 
165  QString accountIdentifier = ui->comboBox->currentAccount()->uniqueIdentifier();
166  m_favoritesProxyModel->setFilterFixedString(accountIdentifier);
167 
168  // Provide only rooms recently used with the selected account for completion
169  m_recentComp->clear();
170 
171  Q_FOREACH (const QString &room, m_recentRooms.value(accountIdentifier)) {
172  m_recentComp->addItem(room);
173  }
174 
175  // Show only rooms recently used with the selected account in the list
176  ui->recentListWidget->clear();
177  ui->recentListWidget->addItems(m_recentRooms.value(accountIdentifier));
178 
179  // Enable/disable the buttons as appropriate
180  bool recentListNonEmpty = m_recentRooms.value(accountIdentifier).size() > 0;
181 
182  ui->clearRecentPushButton->setEnabled(recentListNonEmpty);
183  ui->removeRecentPushButton->setEnabled(recentListNonEmpty);
184 }
185 
186 void KTp::JoinChatRoomDialog::addFavorite()
187 {
188  if (!ui->comboBox->currentAccount()) {
189  return;
190  }
191 
192  bool ok = false;
193  QString favoriteHandle = ui->lineEdit->text();
194  QString favoriteAccount = ui->comboBox->currentAccount()->uniqueIdentifier();
195 
196  if (m_favoritesModel->containsRoom(favoriteHandle, favoriteAccount)) {
197  KMessageBox::sorry(this, i18n("This room is already in your favorites."));
198  } else {
199  QString favoriteName = KInputDialog::getText(i18n("Add room"), i18n("Name"), QString(), &ok);
200 
201  if (ok) {
202  QString key = favoriteHandle + favoriteAccount;
203 
204  // Write it to the config file
205  QVariantList favorite;
206  favorite.append(favoriteName);
207  favorite.append(favoriteHandle);
208  favorite.append(favoriteAccount);
209  m_favoriteRoomsGroup.writeEntry(key, favorite);
210  m_favoriteRoomsGroup.sync();
211 
212  // Insert it into the model
213  QVariantMap room;
214  room.insert(QLatin1String("name"), favoriteName);
215  room.insert(QLatin1String("handle-name"), favoriteHandle);
216  room.insert(QLatin1String("account-identifier"), favoriteAccount);
217  m_favoritesModel->addRoom(room);
218  }
219  }
220 }
221 
222 void KTp::JoinChatRoomDialog::removeFavorite()
223 {
224  QString favoriteHandle = ui->listView->currentIndex().data(FavoriteRoomsModel::HandleNameRole).toString();
225  QString favoriteAccount = ui->comboBox->currentAccount()->uniqueIdentifier();
226  QVariantMap room = ui->listView->currentIndex().data(FavoriteRoomsModel::FavoriteRoomRole).value<QVariantMap>();
227 
228  QString key = favoriteHandle + favoriteAccount;
229 
230  if(m_favoriteRoomsGroup.keyList().contains(key)) {
231  m_favoriteRoomsGroup.deleteEntry(key);
232  m_favoriteRoomsGroup.sync();
233  m_favoritesModel->removeRoom(room);
234 
235  if (m_favoritesModel->countForAccount(favoriteAccount) == 0) {
236  ui->removeFavoritePushButton->setEnabled(false);
237  }
238  }
239 }
240 
241 void KTp::JoinChatRoomDialog::addRecentRoom()
242 {
243  Tp::AccountPtr account = ui->comboBox->currentAccount();
244  if (!account) {
245  return;
246  }
247 
248  QString accountIdentifier = account->uniqueIdentifier();
249  QString handle = ui->lineEdit->text();
250 
251  if (!handle.isEmpty()) {
252  if (m_recentRooms.contains(accountIdentifier)) {
253  QStringList currentList = m_recentRooms.take(accountIdentifier);
254 
255  // If the handle is already in the list move it at the first position
256  // because now it is the most recent
257  if (currentList.contains(handle)) {
258  currentList.move(currentList.indexOf(handle), 0);
259  m_recentRooms.insert(accountIdentifier, currentList);
260  // else just insert it at the first position and check for the size
261  } else {
262  currentList.insert(0, handle);
263 
264  if (currentList.size() > 8) {
265  currentList.removeLast();
266  }
267 
268  m_recentRooms.insert(accountIdentifier, currentList);
269  }
270  } else {
271  m_recentRooms.insert(accountIdentifier, QStringList(handle));
272  }
273 
274  // Write it to the config
275  m_recentRoomsGroup.writeEntry(accountIdentifier, m_recentRooms.value(accountIdentifier));
276  m_recentRoomsGroup.sync();
277  }
278 }
279 
280 void KTp::JoinChatRoomDialog::removeRecentRoom()
281 {
282  QString accountIdentifier = ui->comboBox->currentAccount()->uniqueIdentifier();
283  QString handle = ui->recentListWidget->currentItem()->text();
284 
285  // Remove the entry
286  QStringList currentList = m_recentRooms.take(accountIdentifier);
287  currentList.removeOne(handle);
288  m_recentRooms.insert(accountIdentifier, currentList);
289 
290  // Update the completion and list
291  onAccountSelectionChanged(ui->comboBox->currentIndex());
292 
293  // Write it to the config
294  m_recentRoomsGroup.writeEntry(accountIdentifier, m_recentRooms.value(accountIdentifier));
295  m_recentRoomsGroup.sync();
296 
297  // Disable the button
298  ui->removeRecentPushButton->setEnabled(false);
299 }
300 
301 void KTp::JoinChatRoomDialog::clearRecentRooms()
302 {
303  QString accountIdentifier = ui->comboBox->currentAccount()->uniqueIdentifier();
304 
305  // Remove all entries for the current account
306  m_recentRooms.remove(accountIdentifier);
307 
308  // Update the completion and list
309  onAccountSelectionChanged(ui->comboBox->currentIndex());
310 
311  // Update the config
312  m_recentRoomsGroup.deleteEntry(accountIdentifier);
313  m_recentRoomsGroup.sync();
314 }
315 
316 void KTp::JoinChatRoomDialog::getRoomList()
317 {
318  Tp::AccountPtr account = ui->comboBox->currentAccount();
319  if (!account) {
320  return;
321  }
322 
323  // Clear the list from previous items
324  m_model->clearRoomInfoList();
325 
326  // Build the channelrequest
327  QVariantMap request;
328  request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType"),
329  TP_QT_IFACE_CHANNEL_TYPE_ROOM_LIST);
330  request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType"),
331  Tp::HandleTypeNone);
332 
333  // If the user provided a server use it, else use the standard server for the selected account
334  if (!ui->serverLineEdit->text().isEmpty()) {
335  request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".Type.RoomList.Server"),
336  ui->serverLineEdit->text());
337  }
338 
339  m_pendingRoomListChannel = account->createAndHandleChannel(request, QDateTime::currentDateTime());
340  connect(m_pendingRoomListChannel, SIGNAL(finished(Tp::PendingOperation*)),
341  this, SLOT(onRoomListChannelReadyForHandling(Tp::PendingOperation*)));
342 
343 }
344 
345 void KTp::JoinChatRoomDialog::stopListing()
346 {
347  m_iface->StopListing();
348 }
349 
350 void KTp::JoinChatRoomDialog::onRoomListChannelReadyForHandling(Tp::PendingOperation *operation)
351 {
352  if (operation->isError()) {
353  kDebug() << operation->errorName();
354  kDebug() << operation->errorMessage();
355  QString errorMsg(operation->errorName() + QLatin1String(": ") + operation->errorMessage());
356  sendNotificationToUser(errorMsg);
357  } else {
358  m_roomListChannel = m_pendingRoomListChannel->channel();
359 
360  connect(m_roomListChannel->becomeReady(),
361  SIGNAL(finished(Tp::PendingOperation*)),
362  SLOT(onRoomListChannelReady(Tp::PendingOperation*)));
363  }
364 }
365 
366 void KTp::JoinChatRoomDialog::onRoomListChannelReady(Tp::PendingOperation *operation)
367 {
368  if (operation->isError()) {
369  kDebug() << operation->errorName();
370  kDebug() << operation->errorMessage();
371  QString errorMsg(operation->errorName() + QLatin1String(": ") + operation->errorMessage());
372  sendNotificationToUser(errorMsg);
373  } else {
374  m_iface = m_roomListChannel->interface<Tp::Client::ChannelTypeRoomListInterface>();
375 
376  m_iface->ListRooms();
377 
378  connect(m_iface, SIGNAL(ListingRooms(bool)), SLOT(onListing(bool)));
379  connect(m_iface, SIGNAL(GotRooms(Tp::RoomInfoList)), SLOT(onGotRooms(Tp::RoomInfoList)));
380  }
381 }
382 
383 void KTp::JoinChatRoomDialog::onRoomListChannelClosed(Tp::PendingOperation *operation)
384 {
385  if (operation->isError()) {
386  kDebug() << operation->errorName();
387  kDebug() << operation->errorMessage();
388  QString errorMsg(operation->errorName() + QLatin1String(": ") + operation->errorMessage());
389  sendNotificationToUser(errorMsg);
390  } else {
391  ui->queryPushButton->setEnabled(true);
392  ui->stopPushButton->setEnabled(false);
393  }
394 }
395 
396 void KTp::JoinChatRoomDialog::onListing(bool isListing)
397 {
398  if (isListing) {
399  kDebug() << "listing";
400  ui->queryPushButton->setEnabled(false);
401  ui->stopPushButton->setEnabled(true);
402  } else {
403  kDebug() << "finished listing";
404  Tp::PendingOperation *op = m_roomListChannel->requestClose();
405  connect(op,
406  SIGNAL(finished(Tp::PendingOperation*)),
407  SLOT(onRoomListChannelClosed(Tp::PendingOperation*)));
408  }
409 }
410 
411 void KTp::JoinChatRoomDialog::onGotRooms(Tp::RoomInfoList roomInfoList)
412 {
413  m_model->addRooms(roomInfoList);
414 }
415 
416 void KTp::JoinChatRoomDialog::onFavoriteRoomClicked(const QModelIndex &index)
417 {
418  if (index.isValid()) {
419  ui->removeFavoritePushButton->setEnabled(true);
420  ui->lineEdit->setText(index.data(FavoriteRoomsModel::HandleNameRole).toString());
421  } else {
422  ui->removeFavoritePushButton->setEnabled(false);
423  }
424 }
425 
426 void KTp::JoinChatRoomDialog::onRecentRoomClicked()
427 {
428  ui->removeRecentPushButton->setEnabled(true);
429 }
430 
431 void KTp::JoinChatRoomDialog::onRoomClicked(const QModelIndex& index)
432 {
433  ui->lineEdit->setText(index.data(RoomsModel::HandleNameRole).toString());
434 }
435 
436 QString KTp::JoinChatRoomDialog::selectedChatRoom() const
437 {
438  return ui->lineEdit->text();
439 }
440 
441 void KTp::JoinChatRoomDialog::onTextChanged(QString newText)
442 {
443  if (newText.isEmpty()) {
444  button(Ok)->setEnabled(false);
445  ui->addFavoritePushButton->setEnabled(false);
446  } else {
447  button(Ok)->setEnabled(true);
448  ui->addFavoritePushButton->setEnabled(true);
449  }
450 }
451 
452 void KTp::JoinChatRoomDialog::sendNotificationToUser(const QString& errorMsg)
453 {
454  //The pointer is automatically deleted when the event is closed
455  KNotification *notification;
456  notification = new KNotification(QLatin1String("telepathyError"), this);
457 
458  notification->setText(errorMsg);
459  notification->sendEvent();
460 }
461 
462 void KTp::JoinChatRoomDialog::loadFavoriteRooms()
463 {
464  QList<QVariantMap> roomList;
465 
466  Q_FOREACH(const QString &key, m_favoriteRoomsGroup.keyList()) {
467  QVariantList favorite = m_favoriteRoomsGroup.readEntry(key, QVariantList());
468  QString favoriteName = favorite.at(0).toString();
469  QString favoriteHandle = favorite.at(1).toString();
470  QString favoriteAccount = favorite.at(2).toString();
471 
472  QVariantMap room;
473  room.insert(QLatin1String("name"), favoriteName);
474  room.insert(QLatin1String("handle-name"), favoriteHandle);
475  room.insert(QLatin1String("account-identifier"), favoriteAccount);
476  roomList.append(room);
477  }
478 
479  m_favoritesModel->addRooms(roomList);
480 }
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