1 /*
2     Contact list context menu
3     Copyright (C) 2011  Martin Klapetek <martin.klapetek@gmail.com>
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 #include "context-menu.h"
21 
22 #include <QDebug>
23 #include <QMenu>
24 #include <QAction>
25 #include <QInputDialog>
26 #include <QDesktopServices>
27 
28 #include <KLocalizedString>
29 #include <KMessageBox>
30 
31 #include <KTp/text-parser.h>
32 #include <KTp/Widgets/notification-config-dialog.h>
33 #include <KTp/Widgets/contact-info-dialog.h>
34 #include <KTp/types.h>
35 #include <KTp/Models/contacts-model.h>
36 #include <KTp/Logger/log-manager.h>
37 #include <KTp/Logger/log-entity.h>
38 
39 #include <TelepathyQt/ContactManager>
40 #include <TelepathyQt/Account>
41 #include <TelepathyQt/PendingOperation>
42 
43 #ifdef HAVE_KPEOPLE
44 #include <kpeople/widgets/persondetailsdialog.h>
45 #include <kpeople/widgets/actions.h>
46 #include <kpeople/global.h>
47 #include <kpeople/personsmodel.h>
48 #include <kpeople/persondata.h>
49 #endif
50 
51 #include "dialogs/remove-contact-dialog.h"
52 
53 #include "contact-list-widget_p.h"
54 
ContextMenu(ContactListWidget * mainWidget)55 ContextMenu::ContextMenu(ContactListWidget *mainWidget)
56     : QObject(mainWidget)
57 {
58     m_mainWidget = mainWidget;
59 }
60 
61 
~ContextMenu()62 ContextMenu::~ContextMenu()
63 {
64 
65 }
66 
setAccountManager(const Tp::AccountManagerPtr & accountManager)67 void ContextMenu::setAccountManager(const Tp::AccountManagerPtr &accountManager)
68 {
69     m_accountManager = accountManager;
70     KTp::LogManager::instance()->setAccountManager(accountManager);
71 }
72 
contactContextMenu(const QModelIndex & index)73 QMenu* ContextMenu::contactContextMenu(const QModelIndex &index)
74 {
75     if (!index.isValid()) {
76         return 0;
77     }
78 
79     if (m_accountManager.isNull()) {
80         return 0;
81     }
82 
83     m_currentIndex = index;
84 
85     QAction *action;
86     QMenu *menu = new QMenu();
87     KTp::ContactPtr contact = index.data(KTp::ContactRole).value<KTp::ContactPtr>();
88 
89     if (contact.isNull()) {
90         qWarning() << "Contact is nulled";
91     }
92 
93     Tp::AccountPtr account = index.data(KTp::AccountRole).value<Tp::AccountPtr>();
94 
95     if (account.isNull()) {
96         qWarning() << "Account is nulled";
97     }
98 
99     if (KTp::kpeopleEnabled()) {
100     #ifdef HAVE_KPEOPLE
101         menu->setTitle(index.data(Qt::DisplayRole).toString());
102         if (index.parent().isValid()) {
103             menu->addActions(KPeople::actionsForPerson(index.data(KTp::ContactUriRole).toString(), menu));
104         } else {
105             menu->addActions(KPeople::actionsForPerson(index.data(KTp::PersonIdRole).toString(), menu));
106         }
107     #endif
108     } else {
109         menu->setTitle(contact->alias());
110         //must be a QAction because menu->addAction returns QAction, breaks compilation otherwise
111         action = menu->addAction(i18n("Start Chat..."));
112         action->setIcon(QIcon::fromTheme("text-x-generic"));
113         action->setDisabled(true);
114         connect(action, SIGNAL(triggered(bool)),
115                 SLOT(onStartTextChatTriggered()));
116 
117         if (index.data(KTp::ContactCanTextChatRole).toBool()) {
118             action->setEnabled(true);
119         }
120 
121         action = menu->addAction(i18n("Start Audio Call..."));
122         action->setIcon(QIcon::fromTheme("audio-headset"));
123         action->setDisabled(true);
124         connect(action, SIGNAL(triggered(bool)),
125                 SLOT(onStartAudioChatTriggered()));
126 
127         if (index.data(KTp::ContactCanAudioCallRole).toBool()) {
128             action->setEnabled(true);
129         }
130 
131         action = menu->addAction(i18n("Start Video Call..."));
132         action->setIcon(QIcon::fromTheme("camera-web"));
133         action->setDisabled(true);
134         connect(action, SIGNAL(triggered(bool)),
135                 SLOT(onStartVideoChatTriggered()));
136 
137         if (index.data(KTp::ContactCanVideoCallRole).toBool()) {
138             action->setEnabled(true);
139         }
140 
141         action = menu->addAction(i18n("Send File..."));
142         action->setIcon(QIcon::fromTheme("mail-attachment"));
143         action->setDisabled(true);
144         connect(action, SIGNAL(triggered(bool)),
145                 SLOT(onStartFileTransferTriggered()));
146 
147         if (index.data(KTp::ContactCanFileTransferRole).toBool()) {
148             action->setEnabled(true);
149         }
150 
151         action = menu->addAction(i18n("Share my desktop..."));
152         action->setIcon(QIcon::fromTheme("krfb"));
153         action->setDisabled(true);
154         connect(action, SIGNAL(triggered(bool)),
155                 SLOT(onStartDesktopSharingTriggered()));
156 
157         if (index.data(KTp::ContactTubesRole).toStringList().contains(QLatin1String("rfb"))) {
158             action->setEnabled(true);
159         }
160 
161         action = menu->addAction(i18n("Open Log..."));
162         action->setIcon(QIcon::fromTheme("documentation"));
163         action->setDisabled(true);
164         connect(action, SIGNAL(triggered(bool)),
165                 SLOT(onOpenLogViewerTriggered()));
166 
167         KTp::LogEntity entity(Tp::HandleTypeContact, contact->id());
168         if (KTp::LogManager::instance()->logsExist(account, entity)) {
169             action->setEnabled(true);
170         }
171     }
172 
173     menu->addSeparator();
174     action = menu->addAction(QIcon::fromTheme("dialog-information"), i18n("Configure Notifications..."));
175     action->setEnabled(true);
176     connect(action, SIGNAL(triggered()),
177                            SLOT(onNotificationConfigureTriggered()));
178 
179     // add "goto" submenu for navigating to links the contact has in presence message
180     // first check to see if there are any links in the contact's presence message
181     QStringList contactLinks;
182     QString presenceMsg = index.data(KTp::ContactPresenceMessageRole).toString();
183     if (presenceMsg.isEmpty()) {
184         contactLinks = QStringList();
185     } else {
186         KTp::TextUrlData urls = KTp::TextParser::instance()->extractUrlData(presenceMsg);
187         contactLinks = urls.fixedUrls;
188     }
189 
190     if (!contactLinks.empty()) {
191         QMenu *subMenu = new QMenu(i18np("Presence message link", "Presence message links", contactLinks.count()));
192 
193         foreach(const QString &link, contactLinks) {
194             action = subMenu->addAction(link);
195             action->setData(link);
196         }
197         connect(subMenu, SIGNAL(triggered(QAction*)), this, SLOT(onOpenLinkTriggered(QAction*)));
198         menu->addMenu(subMenu);
199     }
200 
201     menu->addSeparator();
202 
203     Tp::ConnectionPtr accountConnection = account->connection();
204     if (accountConnection.isNull()) {
205         qWarning() << "Account connection is nulled.";
206     }
207 
208     if (m_mainWidget->d_ptr->model->groupMode() == KTp::ContactsModel::GroupGrouping) {
209         // remove contact from group action, must be QAction because menu->addAction returns QAction
210         QAction *groupRemoveAction = menu->addAction(QIcon(), i18n("Remove Contact From This Group"));
211         connect(groupRemoveAction, SIGNAL(triggered(bool)), this, SLOT(onRemoveContactFromGroupTriggered()));
212 
213         if (accountConnection.isNull()) {
214             groupRemoveAction->setDisabled(true);
215         } else if (accountConnection->actualFeatures().contains(Tp::Connection::FeatureRosterGroups)) {
216             QMenu* groupAddMenu = menu->addMenu(i18n("Move to Group"));
217 
218             QStringList groupList;
219             QList<Tp::AccountPtr> accounts = m_accountManager->allAccounts();
220             foreach (const Tp::AccountPtr &account, accounts) {
221                 if (!account->connection().isNull()) {
222                     groupList.append(account->connection()->contactManager()->allKnownGroups());
223                 }
224             }
225 
226             groupList.removeDuplicates();
227 
228             QStringList currentGroups = contact->groups();
229 
230             foreach (const QString &group, currentGroups) {
231                 groupList.removeAll(group);
232             }
233 
234             connect(groupAddMenu->addAction(i18n("Create New Group...")), SIGNAL(triggered(bool)),
235                     this, SLOT(onCreateNewGroupTriggered()));
236 
237             groupAddMenu->addSeparator();
238 
239             foreach (const QString &group, groupList) {
240                 connect(groupAddMenu->addAction(group), SIGNAL(triggered(bool)),
241                         SLOT(onAddContactToGroupTriggered()));
242             }
243         } else {
244             qWarning() << "Unable to support Groups";
245         }
246     }
247 
248     menu->addSeparator();
249 
250     if (!contact.isNull()) {
251         if (contact->manager()->canRequestPresenceSubscription()) {
252             if (contact->subscriptionState() != Tp::Contact::PresenceStateYes) {
253                 action = menu->addAction(i18n("Re-request Contact Authorization"));
254                 connect(action, SIGNAL(triggered(bool)), SLOT(onRerequestAuthorization()));
255             }
256         }
257         if (contact->manager()->canAuthorizePresencePublication()) {
258             if (contact->publishState() != Tp::Contact::PresenceStateYes) {
259                 action = menu->addAction(i18n("Resend Contact Authorization"));
260                 connect(action, SIGNAL(triggered(bool)), SLOT(onResendAuthorization()));
261             }
262         }
263 
264         action = menu->addSeparator(); //prevent two seperators in a row
265 
266         if (contact->isBlocked()) {
267             action = menu->addAction(i18n("Unblock Contact"));
268             connect(action, SIGNAL(triggered(bool)), SLOT(onUnblockContactTriggered()));
269             action->setEnabled(contact->manager()->canBlockContacts());
270         } else {
271             action = menu->addAction(i18n("Block Contact"));
272             connect(action, SIGNAL(triggered(bool)), SLOT(onBlockContactTriggered()));
273             action->setEnabled(contact->manager()->canBlockContacts());
274         }
275 
276         // remove contact action, must be QAction because that's what menu->addAction returns
277         //TODO find an "if canRemove"
278         QAction *removeAction = menu->addAction(QIcon::fromTheme("list-remove-user"), i18n("Remove Contact..."));
279         connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(onDeleteContactTriggered()));
280 
281         menu->addSeparator();
282     }
283 
284     action = menu->addAction(i18n("Show Contact Information..."));
285     action->setIcon(QIcon::fromTheme(""));
286     connect(action, SIGNAL(triggered()), SLOT(onShowInfoTriggered()));
287 
288     return menu;
289 }
290 
groupContextMenu(const QModelIndex & index)291 QMenu* ContextMenu::groupContextMenu(const QModelIndex &index)
292 {
293     if (!index.isValid()) {
294         return 0;
295     }
296 
297     m_currentIndex = index;
298 
299     const QString groupName = index.data(Qt::DisplayRole).toString();
300 
301     QMenu *menu = new QMenu();
302     menu->setTitle(groupName);
303 
304     //must be QAction, because menu->addAction returns QAction, otherwise compilation dies horribly
305     QAction *action = menu->addAction(i18n("Rename Group..."));
306     action->setIcon(QIcon::fromTheme("edit-rename"));
307 
308     connect(action, SIGNAL(triggered(bool)),
309             this, SLOT(onRenameGroupTriggered()));
310 
311     action = menu->addAction(i18n("Delete Group"));
312     action->setIcon(QIcon::fromTheme("edit-delete"));
313 
314     connect(action, SIGNAL(triggered(bool)),
315             this, SLOT(onDeleteGroupTriggered()));
316 
317     return menu;
318 }
319 
onRemoveContactFromGroupTriggered()320 void ContextMenu::onRemoveContactFromGroupTriggered()
321 {
322     if (m_currentIndex.parent().data(KTp::RowTypeRole).toUInt() != KTp::GroupRowType) {
323         return;
324     }
325 
326     const QString groupName = m_currentIndex.parent().data(Qt::DisplayRole).toString();
327     Tp::ContactPtr contact =  m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
328 
329     Tp::PendingOperation *operation = contact->removeFromGroup(groupName);
330 
331     if (operation) {
332         connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
333                 m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
334     }
335 }
336 
onOpenLinkTriggered(QAction * action)337 void ContextMenu::onOpenLinkTriggered(QAction *action)
338 {
339     QDesktopServices::openUrl(QUrl(action->data().toString()));
340 }
341 
onShowInfoTriggered()342 void ContextMenu::onShowInfoTriggered()
343 {
344     if (!m_currentIndex.isValid()) {
345         qWarning() << "Invalid index provided.";
346         return;
347     }
348 
349     if (KTp::kpeopleEnabled()) {
350     #ifdef HAVE_KPEOPLE
351         QString personId = m_currentIndex.data(KTp::PersonIdRole).toString();
352         if (!personId.isEmpty()) {
353             KPeople::PersonDetailsDialog *view = new KPeople::PersonDetailsDialog(m_mainWidget);
354             KPeople::PersonData *person = new KPeople::PersonData(personId, view);
355             view->setPerson(person);
356             view->setAttribute(Qt::WA_DeleteOnClose);
357             view->show();
358         }
359     #endif
360     } else {
361         const Tp::AccountPtr &account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
362         const Tp::ContactPtr &contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
363         if (account && contact) {
364             KTp::ContactInfoDialog* contactInfoDialog = new KTp::ContactInfoDialog(account, contact, m_mainWidget);
365             contactInfoDialog->setAttribute(Qt::WA_DeleteOnClose);
366             contactInfoDialog->show();
367         }
368     }
369 }
370 
onStartTextChatTriggered()371 void ContextMenu::onStartTextChatTriggered()
372 {
373     if (!m_currentIndex.isValid()) {
374         qWarning() << "Invalid index provided.";
375         return;
376     }
377 
378     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
379     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
380 
381     if (contact && account) {
382         m_mainWidget->startTextChannel(account, contact);
383     }
384 }
385 
onStartAudioChatTriggered()386 void ContextMenu::onStartAudioChatTriggered()
387 {
388     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
389     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
390 
391     if (contact && account) {
392         m_mainWidget->startAudioChannel(account, contact);
393     }
394 }
395 
onStartVideoChatTriggered()396 void ContextMenu::onStartVideoChatTriggered()
397 {
398     if (!m_currentIndex.isValid()) {
399         qWarning() << "Invalid index provided.";
400         return;
401     }
402 
403     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
404     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
405 
406     if (contact && account) {
407         m_mainWidget->startVideoChannel(account, contact);
408     }
409 }
410 
onStartFileTransferTriggered()411 void ContextMenu::onStartFileTransferTriggered()
412 {
413     if (!m_currentIndex.isValid()) {
414         qWarning() << "Invalid index provided.";
415         return;
416     }
417 
418     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
419     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
420 
421     if (contact && account) {
422         m_mainWidget->startFileTransferChannel(account, contact);
423     }
424 }
425 
onStartDesktopSharingTriggered()426 void ContextMenu::onStartDesktopSharingTriggered()
427 {
428     if (!m_currentIndex.isValid()) {
429         qWarning() << "Invalid index provided.";
430         return;
431     }
432 
433     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
434     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
435 
436     if (contact && account) {
437         m_mainWidget->startDesktopSharing(account, contact);
438     }
439 }
440 
onOpenLogViewerTriggered()441 void ContextMenu::onOpenLogViewerTriggered()
442 {
443     if (!m_currentIndex.isValid()) {
444       qWarning() << "Invalid index provided.";
445       return;
446     }
447 
448     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
449     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
450 
451     if (contact && account) {
452         m_mainWidget->startLogViewer(account, contact);
453     }
454 }
455 
onUnblockContactTriggered()456 void ContextMenu::onUnblockContactTriggered()
457 {
458     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
459 
460     Tp::PendingOperation *operation = contact->unblock(); //FIXME
461     connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
462             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
463 }
464 
onAddContactToGroupTriggered()465 void ContextMenu::onAddContactToGroupTriggered()
466 {
467     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
468 
469     QAction *action = qobject_cast<QAction*>(sender());
470     if (!action) {
471         qWarning() << "Invalid action";
472         return;
473     }
474 
475     const QStringList currentGroups = contact->groups();
476 
477     Tp::PendingOperation* operation = contact->addToGroup(action->text().remove('&'));
478 
479     if (operation) {
480         connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
481                 m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
482 
483         foreach (const QString &group, currentGroups) {
484             Tp::PendingOperation* operation = contact->removeFromGroup(group);
485             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
486                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
487         }
488     }
489 }
490 
onCreateNewGroupTriggered()491 void ContextMenu::onCreateNewGroupTriggered()
492 {
493     bool ok = false;
494 
495     QString newGroupName = QInputDialog::getText(0, i18n("New Group Name"),
496                                                  i18n("Please enter the new group name"),
497                                                  QLineEdit::Normal,
498                                                  QString(),
499                                                  &ok);
500 
501     if (ok) {
502         Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
503         Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
504 
505         connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
506                 m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
507     }
508 }
509 
onRenameGroupTriggered()510 void ContextMenu::onRenameGroupTriggered()
511 {
512     if (m_currentIndex.data(KTp::RowTypeRole).toUInt() != KTp::GroupRowType) {
513         return;
514     }
515 
516     const QString groupName = m_currentIndex.data(Qt::DisplayRole).toString();
517     const QAbstractItemModel *model = m_currentIndex.model();
518 
519     bool ok = false;
520 
521     QString newGroupName = QInputDialog::getText(0, i18n("New Group Name"),
522                                                  i18n("Please enter the new group name"),
523                                                  QLineEdit::Normal,
524                                                  groupName,
525                                                  &ok);
526 
527     if (ok && groupName != newGroupName) {
528         //loop through all child indexes of m_currentIndex
529         for(int i = 0; i < model->rowCount(m_currentIndex); i++) {
530             Tp::ContactPtr contact = model->index(i, 0 , m_currentIndex).data(KTp::ContactRole).value<KTp::ContactPtr>();
531             Q_ASSERT(contact);
532 
533             Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
534             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
535                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
536 
537             operation = contact->removeFromGroup(groupName);
538             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
539                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
540         }
541     }
542 }
543 
onDeleteGroupTriggered()544 void ContextMenu::onDeleteGroupTriggered()
545 {
546     if (m_accountManager.isNull() ||
547         (m_currentIndex.data(KTp::RowTypeRole).toUInt() != KTp::GroupRowType)) {
548         return;
549     }
550 
551     const QString groupName = m_currentIndex.data(Qt::DisplayRole).toString();
552     const QAbstractItemModel *model = m_currentIndex.model();
553 
554 
555     if (KMessageBox::warningContinueCancel(m_mainWidget,
556                                            i18n("Do you really want to remove group %1?\n\n"
557                                                 "Note that all contacts will be moved to group 'Ungrouped'", groupName),
558                                            i18n("Remove Group")) == KMessageBox::Continue) {
559 
560         for(int i = 0; i < model->rowCount(m_currentIndex); i++) {
561             Tp::ContactPtr contact = model->index(i, 0 , m_currentIndex).data(KTp::ContactRole).value<KTp::ContactPtr>();
562 
563             Q_ASSERT(contact);
564 
565             Tp::PendingOperation *operation = contact->removeFromGroup(groupName);
566             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
567                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
568         }
569 
570         foreach (const Tp::AccountPtr &account, m_accountManager->allAccounts()) {
571             if (account->connection()) {
572                 Tp::PendingOperation *operation = account->connection()->contactManager()->removeGroup(groupName);
573                 connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
574                         m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
575             }
576         }
577     }
578 }
579 
onBlockContactTriggered()580 void ContextMenu::onBlockContactTriggered()
581 {
582     Tp::ContactPtr contact =  m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
583 
584     Tp::PendingOperation *operation = contact->block();
585     connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
586             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
587 }
588 
onDeleteContactTriggered()589 void ContextMenu::onDeleteContactTriggered()
590 {
591     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
592 
593     QList<Tp::ContactPtr>contactList;
594     contactList.append(contact);
595 
596     // ask for confirmation
597     QPointer<RemoveContactDialog> removeDialog = new RemoveContactDialog(contact, m_mainWidget);
598 
599     if (removeDialog.data()->exec() == QDialog::Accepted) {
600         if (!removeDialog.isNull()) {
601             // remove from contact list
602             Tp::PendingOperation *deleteOp = contact->manager()->removeContacts(contactList);
603             connect(deleteOp, SIGNAL(finished(Tp::PendingOperation*)),
604                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
605 
606             if (removeDialog.data()->blockContact()) {
607                 // block contact
608                 Tp::PendingOperation *blockOp = contact->manager()->blockContacts(contactList);
609                 connect(blockOp, SIGNAL(finished(Tp::PendingOperation*)),
610                         m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
611             }
612         }
613     }
614 
615     delete removeDialog.data();
616 }
617 
onRerequestAuthorization()618 void ContextMenu::onRerequestAuthorization()
619 {
620     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
621     Tp::PendingOperation *op = contact->manager()->requestPresenceSubscription(QList<Tp::ContactPtr>() << contact);
622     connect(op, SIGNAL(finished(Tp::PendingOperation*)),
623             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
624 }
625 
onResendAuthorization()626 void ContextMenu::onResendAuthorization()
627 {
628     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
629     Tp::PendingOperation *op = contact->manager()->authorizePresencePublication(QList<Tp::ContactPtr>() << contact);
630     connect(op, SIGNAL(finished(Tp::PendingOperation*)),
631             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
632 }
633 
onNotificationConfigureTriggered()634 void ContextMenu::onNotificationConfigureTriggered()
635 {
636     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
637 
638     KTp::NotificationConfigDialog *notificationDialog = new KTp::NotificationConfigDialog(contact, m_mainWidget);
639     notificationDialog->show();
640 }
641