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 #include "debug.h"
25
26 #include <KTp/Models/rooms-model.h>
27
28 #include <KConfig>
29 #include <KConfigGroup>
30 #include <KSharedConfig>
31 #include <KMessageWidget>
32 #include <KLocalizedString>
33 #include <KNotification>
34 #include <KIconLoader>
35
36 #include <TelepathyQt/Account>
37 #include <TelepathyQt/AccountSet>
38 #include <TelepathyQt/AccountCapabilityFilter>
39 #include <TelepathyQt/AccountManager>
40 #include <TelepathyQt/AccountPropertyFilter>
41 #include <TelepathyQt/AndFilter>
42 #include <TelepathyQt/ChannelTypeRoomListInterface>
43 #include <TelepathyQt/PendingChannel>
44 #include <TelepathyQt/PendingReady>
45 #include <TelepathyQt/RequestableChannelClassSpec>
46 #include <TelepathyQt/RoomListChannel>
47 #include <TelepathyQt/PendingChannelRequest>
48
49 #include <QSortFilterProxyModel>
50 #include <QDialogButtonBox>
51
52 class KTp::JoinChatRoomDialog::Private
53 {
54 public:
Private(JoinChatRoomDialog * q)55 Private(JoinChatRoomDialog *q) :
56 ui(new Ui::JoinChatRoomDialog)
57 , model(new RoomsModel(q))
58 , favoritesModel(new FavoriteRoomsModel(q))
59 , favoritesProxyModel(new QSortFilterProxyModel(q))
60 , joinInProgress(false)
61 {}
62
63 QList<Tp::AccountPtr> accounts;
64 Ui::JoinChatRoomDialog *ui;
65 QDialogButtonBox *buttonBox;
66 Tp::PendingChannel *pendingRoomListChannel;
67 Tp::ChannelPtr roomListChannel;
68 Tp::Client::ChannelTypeRoomListInterface *iface;
69 RoomsModel *model;
70 FavoriteRoomsModel *favoritesModel;
71 QSortFilterProxyModel *favoritesProxyModel;
72 KConfigGroup favoriteRoomsGroup;
73 KConfigGroup recentRoomsGroup;
74 bool joinInProgress;
75 };
76
JoinChatRoomDialog(Tp::AccountManagerPtr accountManager,QWidget * parent)77 KTp::JoinChatRoomDialog::JoinChatRoomDialog(Tp::AccountManagerPtr accountManager, QWidget* parent)
78 : QDialog(parent, Qt::Dialog)
79 , d(new Private(this))
80 {
81 QWidget *joinChatRoomDialog = new QWidget(this);
82 d->ui->setupUi(joinChatRoomDialog);
83 d->ui->feedbackWidget->hide();
84
85 d->buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
86
87 QVBoxLayout *mainLayout = new QVBoxLayout(this);
88 mainLayout->addWidget(joinChatRoomDialog);
89 mainLayout->addWidget(d->buttonBox);
90 setLayout(mainLayout);
91
92 setWindowIcon(QIcon::fromTheme(QLatin1String("im-irc")));
93 setWindowTitle(i18nc("Dialog title", "Join Chat Room"));
94
95 d->ui->filterPicture->clear();
96 d->ui->filterPicture->setPixmap(KIconLoader::global()->loadIcon(QLatin1String("view-filter"), KIconLoader::Small));
97
98 // config
99 KSharedConfigPtr commonConfig = KSharedConfig::openConfig(QLatin1String("ktelepathyrc"));
100 d->favoriteRoomsGroup = commonConfig->group(QLatin1String("FavoriteRooms"));
101 d->recentRoomsGroup = commonConfig->group(QLatin1String("RecentChatRooms"));
102
103 // load favorite and recent rooms
104 loadFavoriteRooms();
105
106 // disable OK button on start
107 d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
108 d->buttonBox->button(QDialogButtonBox::Ok)->setText(i18nc("button", "Join/Create"));
109 d->buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon::fromTheme(QLatin1String("im-irc")));
110
111 onAccountSelectionChanged(d->ui->comboBox->currentIndex());
112 connect(accountManager->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)),
113 this, SLOT(onAccountManagerReady(Tp::PendingOperation*)));
114
115 // Previous Tab
116 d->favoritesProxyModel->setSourceModel(d->favoritesModel);
117 d->favoritesProxyModel->setFilterKeyColumn(FavoriteRoomsModel::AccountIdentifierColumn);
118 d->favoritesProxyModel->setSortRole(Qt::CheckStateRole);
119 d->favoritesProxyModel->setDynamicSortFilter(true);
120
121 d->ui->previousView->setModel(d->favoritesProxyModel);
122 d->ui->previousView->setHeaderHidden(true);
123 d->ui->previousView->header()->setStretchLastSection(false);
124 d->ui->previousView->header()->setSectionResizeMode(FavoriteRoomsModel::BookmarkColumn, QHeaderView::ResizeToContents);
125 d->ui->previousView->header()->setSectionResizeMode(FavoriteRoomsModel::HandleNameColumn, QHeaderView::Stretch);
126 d->ui->previousView->setColumnHidden(FavoriteRoomsModel::AccountIdentifierColumn, true);
127 d->ui->previousView->sortByColumn(FavoriteRoomsModel::BookmarkColumn, Qt::DescendingOrder);
128
129 // Search Tab
130 QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
131 proxyModel->setSourceModel(d->model);
132 proxyModel->setSortLocaleAware(true);
133 proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
134 proxyModel->setFilterKeyColumn(RoomsModel::NameColumn);
135 proxyModel->setDynamicSortFilter(true);
136
137 d->ui->queryView->setModel(proxyModel);
138 d->ui->queryView->header()->setStretchLastSection(false);
139 d->ui->queryView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
140 d->ui->queryView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
141 d->ui->queryView->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
142 d->ui->queryView->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
143 d->ui->queryView->header()->setSortIndicatorShown(false);
144 d->ui->queryView->sortByColumn(RoomsModel::NameColumn, Qt::AscendingOrder);
145
146 // connects
147 connect(d->ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
148 connect(d->ui->previousView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
149 connect(d->ui->previousView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
150 this, SLOT(onFavoriteRoomSelectionChanged(QModelIndex,QModelIndex)));
151 connect(d->favoritesModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
152 this, SLOT(onFavoriteRoomDataChanged(QModelIndex,QModelIndex)));
153 connect(d->ui->clearRecentPushButton, SIGNAL(clicked(bool)), this, SLOT(clearRecentRooms()));
154 connect(d->ui->serverLineEdit, SIGNAL(returnPressed()), this, SLOT(getRoomList()));
155 connect(d->ui->queryButton, SIGNAL(clicked(bool)), this, SLOT(getRoomList()));
156 connect(d->ui->queryView, SIGNAL(clicked(QModelIndex)), this, SLOT(onRoomClicked(QModelIndex)));
157 connect(d->ui->queryView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
158 connect(d->ui->filterBar, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterFixedString(QString)));
159 connect(d->ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onAccountSelectionChanged(int)));
160 connect(d->buttonBox, SIGNAL(accepted()), this, SLOT(addRecentRoom()));
161 connect(d->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); //FIXME?
162 connect(d->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
163 }
164
closeEvent(QCloseEvent * e)165 void KTp::JoinChatRoomDialog::closeEvent(QCloseEvent* e)
166 {
167 // ignore close event if we are in the middle of an operation
168 if (!d->joinInProgress) {
169 QDialog::closeEvent(e);
170 }
171 }
172
173
onAccountManagerReady(Tp::PendingOperation * operation)174 void KTp::JoinChatRoomDialog::onAccountManagerReady(Tp::PendingOperation* operation)
175 {
176 Tp::AccountManagerPtr accountManager = Tp::AccountManagerPtr::qObjectCast(
177 qobject_cast<Tp::PendingReady*>(operation)->proxy()
178 );
179 Tp::AccountPropertyFilterPtr isOnlineFilter = Tp::AccountPropertyFilter::create();
180 isOnlineFilter->addProperty(QLatin1String("online"), true);
181
182 Tp::AccountCapabilityFilterPtr capabilityFilter = Tp::AccountCapabilityFilter::create(
183 Tp::RequestableChannelClassSpecList() << Tp::RequestableChannelClassSpec::textChatroom());
184 Tp::AccountFilterPtr filter = Tp::AndFilter<Tp::Account>::create((QList<Tp::AccountFilterConstPtr>() <<
185 isOnlineFilter <<
186 capabilityFilter));
187
188 d->ui->comboBox->setAccountSet(accountManager->filterAccounts(filter));
189
190 // queryTab
191 if (d->ui->comboBox->count() > 0) {
192 d->ui->queryButton->setEnabled(true);
193 }
194
195 // apply the filter after populating
196 onAccountSelectionChanged(d->ui->comboBox->currentIndex());
197 }
198
~JoinChatRoomDialog()199 KTp::JoinChatRoomDialog::~JoinChatRoomDialog()
200 {
201 delete d->ui;
202 delete d;
203 }
204
selectedAccount() const205 Tp::AccountPtr KTp::JoinChatRoomDialog::selectedAccount() const
206 {
207 return d->ui->comboBox->currentAccount();
208 }
209
accept()210 void KTp::JoinChatRoomDialog::accept()
211 {
212 d->ui->feedbackWidget->hide();
213 const Tp::AccountPtr account = selectedAccount();
214 if (account) {
215 setJoinInProgress(true);
216 Tp::PendingChannelRequest *request = account->ensureTextChatroom(selectedChatRoom());
217 connect(request, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onStartChatFinished(Tp::PendingOperation*)));
218 }
219 }
220
221
onAccountSelectionChanged(int newIndex)222 void KTp::JoinChatRoomDialog::onAccountSelectionChanged(int newIndex)
223 {
224 // Show only favorites associated with the selected account
225 Q_UNUSED(newIndex)
226
227 if (!d->ui->comboBox->currentAccount()) {
228 // Set a filter expression that matches no account identifier
229 d->favoritesProxyModel->setFilterRegExp(QLatin1String("a^"));
230 return;
231 }
232
233 QString accountIdentifier = d->ui->comboBox->currentAccount()->uniqueIdentifier();
234 d->favoritesProxyModel->setFilterFixedString(accountIdentifier);
235
236 // Enable/disable the buttons as appropriate
237 d->ui->clearRecentPushButton->setEnabled(!d->recentRoomsGroup.keyList().empty());
238 }
239
onFavoriteRoomDataChanged(const QModelIndex & topLeft,const QModelIndex & bottomRight)240 void KTp::JoinChatRoomDialog::onFavoriteRoomDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
241 {
242 // Because previousView only allows editing of a single row, assume that topLeft points to the changed data.
243 Q_UNUSED(bottomRight);
244
245 bool bookmarked = topLeft.data(Qt::CheckStateRole) == Qt::Checked ? true : false;
246 const QString &favoriteHandle = topLeft.data(FavoriteRoomsModel::HandleNameRole).toString();
247 const QString &favoriteAccount = topLeft.data(FavoriteRoomsModel::AccountRole).toString();
248
249 const QString &key = favoriteHandle + favoriteAccount;
250
251 // Write the changed room to the config file
252 QVariantList favorite;
253 favorite.append(favoriteHandle);
254 favorite.append(favoriteAccount);
255
256 if (bookmarked) {
257 if (d->recentRoomsGroup.keyList().contains(key)) {
258 d->recentRoomsGroup.deleteEntry(key);
259 d->recentRoomsGroup.sync();
260 }
261 d->favoriteRoomsGroup.writeEntry(key, favorite);
262 d->favoriteRoomsGroup.sync();
263 } else {
264 if (d->favoriteRoomsGroup.keyList().contains(key)) {
265 d->favoriteRoomsGroup.deleteEntry(key);
266 d->favoriteRoomsGroup.sync();
267 }
268 d->recentRoomsGroup.writeEntry(key, favorite);
269 d->recentRoomsGroup.sync();
270 }
271
272 onAccountSelectionChanged(d->ui->comboBox->currentIndex());
273 }
274
addRecentRoom()275 void KTp::JoinChatRoomDialog::addRecentRoom()
276 {
277 Tp::AccountPtr account = d->ui->comboBox->currentAccount();
278 if (!account || d->ui->lineEdit->text().isEmpty()) {
279 return;
280 }
281
282 QString recentAccount = account->uniqueIdentifier();
283 QString recentHandle = d->ui->lineEdit->text();
284 const QString &key = recentHandle + recentAccount;
285
286 QVariantList recent;
287 recent.append(recentHandle);
288 recent.append(recentAccount);
289
290 if(d->favoriteRoomsGroup.keyList().contains(key) || d->recentRoomsGroup.keyList().contains(key)) {
291 return;
292 }
293
294 d->recentRoomsGroup.writeEntry(key, recent);
295 d->recentRoomsGroup.sync();
296 }
297
298
clearRecentRooms()299 void KTp::JoinChatRoomDialog::clearRecentRooms()
300 {
301 QString accountIdentifier = d->ui->comboBox->currentAccount()->uniqueIdentifier();
302
303 KSharedConfigPtr commonConfig = KSharedConfig::openConfig(QLatin1String("ktelepathyrc"));
304 commonConfig->deleteGroup(QLatin1String("RecentChatRooms"));
305 commonConfig->sync();
306
307 // Reload the model
308 d->favoritesModel->clearRooms();
309 loadFavoriteRooms();
310
311 // Update the list
312 onAccountSelectionChanged(d->ui->comboBox->currentIndex());
313 }
314
getRoomList()315 void KTp::JoinChatRoomDialog::getRoomList()
316 {
317 Tp::AccountPtr account = d->ui->comboBox->currentAccount();
318 if (!account) {
319 return;
320 }
321
322 // Clear the list from previous items
323 d->model->clearRoomInfoList();
324
325 // Build the channelrequest
326 QVariantMap request;
327 request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType"),
328 TP_QT_IFACE_CHANNEL_TYPE_ROOM_LIST);
329 request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType"),
330 Tp::HandleTypeNone);
331
332 // If the user provided a server use it, else use the standard server for the selected account
333 if (!d->ui->serverLineEdit->text().isEmpty()) {
334 request.insert(TP_QT_IFACE_CHANNEL_TYPE_ROOM_LIST + QLatin1String(".Server"),
335 d->ui->serverLineEdit->text());
336 }
337
338 d->pendingRoomListChannel = account->createAndHandleChannel(request, QDateTime::currentDateTime());
339 connect(d->pendingRoomListChannel, SIGNAL(finished(Tp::PendingOperation*)),
340 this, SLOT(onRoomListChannelReadyForHandling(Tp::PendingOperation*)));
341
342 }
343
stopListing()344 void KTp::JoinChatRoomDialog::stopListing()
345 {
346 d->iface->StopListing();
347 }
348
onRoomListChannelReadyForHandling(Tp::PendingOperation * operation)349 void KTp::JoinChatRoomDialog::onRoomListChannelReadyForHandling(Tp::PendingOperation *operation)
350 {
351 if (operation->isError()) {
352 qCDebug(KTP_WIDGETS) << operation->errorName();
353 qCDebug(KTP_WIDGETS) << operation->errorMessage();
354 QString errorMsg(operation->errorName() + QLatin1String(": ") + operation->errorMessage());
355 sendNotificationToUser(errorMsg);
356 } else {
357 d->roomListChannel = d->pendingRoomListChannel->channel();
358
359 connect(d->roomListChannel->becomeReady(),
360 SIGNAL(finished(Tp::PendingOperation*)),
361 SLOT(onRoomListChannelReady(Tp::PendingOperation*)));
362 }
363 }
364
onRoomListChannelReady(Tp::PendingOperation * operation)365 void KTp::JoinChatRoomDialog::onRoomListChannelReady(Tp::PendingOperation *operation)
366 {
367 if (operation->isError()) {
368 qCDebug(KTP_WIDGETS) << operation->errorName();
369 qCDebug(KTP_WIDGETS) << operation->errorMessage();
370 QString errorMsg(operation->errorName() + QLatin1String(": ") + operation->errorMessage());
371 sendNotificationToUser(errorMsg);
372 } else {
373 d->iface = d->roomListChannel->interface<Tp::Client::ChannelTypeRoomListInterface>();
374
375 d->iface->ListRooms();
376
377 connect(d->iface, SIGNAL(ListingRooms(bool)), SLOT(onListing(bool)));
378 connect(d->iface, SIGNAL(GotRooms(Tp::RoomInfoList)), SLOT(onGotRooms(Tp::RoomInfoList)));
379 }
380 }
381
onRoomListChannelClosed(Tp::PendingOperation * operation)382 void KTp::JoinChatRoomDialog::onRoomListChannelClosed(Tp::PendingOperation *operation)
383 {
384 if (operation->isError()) {
385 qCDebug(KTP_WIDGETS) << operation->errorName();
386 qCDebug(KTP_WIDGETS) << operation->errorMessage();
387 QString errorMsg(operation->errorName() + QLatin1String(": ") + operation->errorMessage());
388 sendNotificationToUser(errorMsg);
389 } else {
390 d->ui->queryButton->setEnabled(true);
391 d->ui->queryButton->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start")));
392 d->ui->queryButton->setText(i18nc("Button text", "Query"));
393 d->ui->queryButton->setToolTip(i18nc("Tooltip text", "Start query"));
394 connect(d->ui->queryButton, SIGNAL(clicked(bool)), this, SLOT(getRoomList()));
395 disconnect(d->ui->queryButton, SIGNAL(clicked(bool)), this, SLOT(stopListing()));
396 }
397 }
398
onListing(bool isListing)399 void KTp::JoinChatRoomDialog::onListing(bool isListing)
400 {
401 if (isListing) {
402 qCDebug(KTP_WIDGETS) << "listing";
403 d->ui->queryButton->setEnabled(true);
404 d->ui->queryButton->setIcon(QIcon::fromTheme(QLatin1String("media-playback-stop")));
405 d->ui->queryButton->setText(i18nc("Button text", "Stop"));
406 d->ui->queryButton->setToolTip(i18nc("Tooltip text", "Stop query"));
407 disconnect(d->ui->queryButton, SIGNAL(clicked(bool)), this, SLOT(getRoomList()));
408 connect(d->ui->queryButton, SIGNAL(clicked(bool)), this, SLOT(stopListing()));
409 } else {
410 qCDebug(KTP_WIDGETS) << "finished listing";
411 Tp::PendingOperation *op = d->roomListChannel->requestClose();
412 connect(op,
413 SIGNAL(finished(Tp::PendingOperation*)),
414 SLOT(onRoomListChannelClosed(Tp::PendingOperation*)));
415 }
416 }
417
onGotRooms(Tp::RoomInfoList roomInfoList)418 void KTp::JoinChatRoomDialog::onGotRooms(Tp::RoomInfoList roomInfoList)
419 {
420 d->model->addRooms(roomInfoList);
421 }
422
onFavoriteRoomSelectionChanged(const QModelIndex & current,const QModelIndex & previous)423 void KTp::JoinChatRoomDialog::onFavoriteRoomSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous)
424 {
425 Q_UNUSED(previous);
426 if (current.isValid()) {
427 d->ui->lineEdit->setText(current.data(FavoriteRoomsModel::HandleNameRole).toString());
428 }
429 }
430
onRoomClicked(const QModelIndex & index)431 void KTp::JoinChatRoomDialog::onRoomClicked(const QModelIndex &index)
432 {
433 d->ui->lineEdit->setText(index.data(RoomsModel::HandleNameRole).toString());
434 }
435
selectedChatRoom() const436 QString KTp::JoinChatRoomDialog::selectedChatRoom() const
437 {
438 return d->ui->lineEdit->text();
439 }
440
onTextChanged(QString newText)441 void KTp::JoinChatRoomDialog::onTextChanged(QString newText)
442 {
443 d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty());
444 }
445
onStartChatFinished(Tp::PendingOperation * op)446 void KTp::JoinChatRoomDialog::onStartChatFinished(Tp::PendingOperation *op)
447 {
448 setJoinInProgress(false);
449 if (op->isError()) {
450 qCDebug(KTP_WIDGETS) << "failed to join room";
451 qCDebug(KTP_WIDGETS) << op->errorName() << op->errorMessage();
452
453 d->ui->feedbackWidget->setMessageType(KMessageWidget::KMessageWidget::Error);
454 d->ui->feedbackWidget->setText(i18n("Could not join chatroom"));
455 d->ui->feedbackWidget->animatedShow();
456 } else {
457 close();
458 }
459 }
460
setJoinInProgress(bool inProgress)461 void KTp::JoinChatRoomDialog::setJoinInProgress(bool inProgress)
462 {
463 d->joinInProgress = inProgress;
464 layout()->parentWidget()->setEnabled(!inProgress);
465 d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!inProgress);
466 d->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(!inProgress);
467 }
468
469
sendNotificationToUser(const QString & errorMsg)470 void KTp::JoinChatRoomDialog::sendNotificationToUser(const QString& errorMsg)
471 {
472 //The pointer is automatically deleted when the event is closed
473 KNotification *notification;
474 notification = new KNotification(QLatin1String("telepathyError"), this);
475
476 notification->setText(errorMsg);
477 notification->sendEvent();
478 }
479
loadFavoriteRooms()480 void KTp::JoinChatRoomDialog::loadFavoriteRooms()
481 {
482 QList<QVariantMap> roomList;
483
484 Q_FOREACH(const QString &key, d->favoriteRoomsGroup.keyList()) {
485 QVariantList favorite = d->favoriteRoomsGroup.readEntry(key, QVariantList());
486 // Keep compatibility with KTp 0.8 and previous
487 if(favorite.size() == 3) {
488 // Update the entry in the config file
489 favorite.removeFirst();
490 d->favoriteRoomsGroup.writeEntry(key, favorite);
491 d->favoriteRoomsGroup.sync();
492 }
493 QString favoriteHandle = favorite.at(0).toString();
494 QString favoriteAccount = favorite.at(1).toString();
495 QVariantMap room;
496 room.insert(QLatin1String("is-bookmarked"), true);
497 room.insert(QLatin1String("handle-name"), favoriteHandle);
498 room.insert(QLatin1String("account-identifier"), favoriteAccount);
499 roomList.append(room);
500 }
501
502 Q_FOREACH (const QString &key, d->recentRoomsGroup.keyList()) {
503 QVariantList recent = d->recentRoomsGroup.readEntry(key, QVariantList());
504 QString recentHandle = recent.at(0).toString();
505 QString recentAccount = recent.at(1).toString();
506 QVariantMap room;
507 room.insert(QLatin1String("is-bookmarked"), false);
508 room.insert(QLatin1String("handle-name"), recentHandle);
509 room.insert(QLatin1String("account-identifier"), recentAccount);
510 roomList.append(room);
511 }
512
513 d->favoritesModel->addRooms(roomList);
514 }
515