Warning, file /network/ktp-contact-list/context-menu.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     Contact list context menu
0003     Copyright (C) 2011  Martin Klapetek <martin.klapetek@gmail.com>
0004 
0005     This library is free software; you can redistribute it and/or
0006     modify it under the terms of the GNU Lesser General Public
0007     License as published by the Free Software Foundation; either
0008     version 2.1 of the License, or (at your option) any later version.
0009 
0010     This library is distributed in the hope that it will be useful,
0011     but WITHOUT ANY WARRANTY; without even the implied warranty of
0012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013     Lesser General Public License for more details.
0014 
0015     You should have received a copy of the GNU Lesser General Public
0016     License along with this library; if not, write to the Free Software
0017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018 */
0019 
0020 #include "context-menu.h"
0021 
0022 #include <QDebug>
0023 #include <QMenu>
0024 #include <QAction>
0025 #include <QInputDialog>
0026 #include <QDesktopServices>
0027 
0028 #include <KLocalizedString>
0029 #include <KMessageBox>
0030 
0031 #include <KTp/text-parser.h>
0032 #include <KTp/Widgets/notification-config-dialog.h>
0033 #include <KTp/Widgets/contact-info-dialog.h>
0034 #include <KTp/types.h>
0035 #include <KTp/Models/contacts-model.h>
0036 #include <KTp/Logger/log-manager.h>
0037 #include <KTp/Logger/log-entity.h>
0038 
0039 #include <TelepathyQt/ContactManager>
0040 #include <TelepathyQt/Account>
0041 #include <TelepathyQt/PendingOperation>
0042 
0043 #ifdef HAVE_KPEOPLE
0044 #include <kpeople/widgets/persondetailsdialog.h>
0045 #include <kpeople/widgets/actions.h>
0046 #include <kpeople/global.h>
0047 #include <kpeople/personsmodel.h>
0048 #include <kpeople/persondata.h>
0049 #endif
0050 
0051 #include "dialogs/remove-contact-dialog.h"
0052 
0053 #include "contact-list-widget_p.h"
0054 
0055 ContextMenu::ContextMenu(ContactListWidget *mainWidget)
0056     : QObject(mainWidget)
0057 {
0058     m_mainWidget = mainWidget;
0059 }
0060 
0061 
0062 ContextMenu::~ContextMenu()
0063 {
0064 
0065 }
0066 
0067 void ContextMenu::setAccountManager(const Tp::AccountManagerPtr &accountManager)
0068 {
0069     m_accountManager = accountManager;
0070     KTp::LogManager::instance()->setAccountManager(accountManager);
0071 }
0072 
0073 QMenu* ContextMenu::contactContextMenu(const QModelIndex &index)
0074 {
0075     if (!index.isValid()) {
0076         return 0;
0077     }
0078 
0079     if (m_accountManager.isNull()) {
0080         return 0;
0081     }
0082 
0083     m_currentIndex = index;
0084 
0085     QAction *action;
0086     QMenu *menu = new QMenu();
0087     KTp::ContactPtr contact = index.data(KTp::ContactRole).value<KTp::ContactPtr>();
0088 
0089     if (contact.isNull()) {
0090         qWarning() << "Contact is nulled";
0091     }
0092 
0093     Tp::AccountPtr account = index.data(KTp::AccountRole).value<Tp::AccountPtr>();
0094 
0095     if (account.isNull()) {
0096         qWarning() << "Account is nulled";
0097     }
0098 
0099     if (KTp::kpeopleEnabled()) {
0100     #ifdef HAVE_KPEOPLE
0101         menu->setTitle(index.data(Qt::DisplayRole).toString());
0102         if (index.parent().isValid()) {
0103             menu->addActions(KPeople::actionsForPerson(index.data(KTp::ContactUriRole).toString(), menu));
0104         } else {
0105             menu->addActions(KPeople::actionsForPerson(index.data(KTp::PersonIdRole).toString(), menu));
0106         }
0107     #endif
0108     } else {
0109         menu->setTitle(contact->alias());
0110         //must be a QAction because menu->addAction returns QAction, breaks compilation otherwise
0111         action = menu->addAction(i18n("Start Chat..."));
0112         action->setIcon(QIcon::fromTheme("text-x-generic"));
0113         action->setDisabled(true);
0114         connect(action, SIGNAL(triggered(bool)),
0115                 SLOT(onStartTextChatTriggered()));
0116 
0117         if (index.data(KTp::ContactCanTextChatRole).toBool()) {
0118             action->setEnabled(true);
0119         }
0120 
0121         action = menu->addAction(i18n("Start Audio Call..."));
0122         action->setIcon(QIcon::fromTheme("audio-headset"));
0123         action->setDisabled(true);
0124         connect(action, SIGNAL(triggered(bool)),
0125                 SLOT(onStartAudioChatTriggered()));
0126 
0127         if (index.data(KTp::ContactCanAudioCallRole).toBool()) {
0128             action->setEnabled(true);
0129         }
0130 
0131         action = menu->addAction(i18n("Start Video Call..."));
0132         action->setIcon(QIcon::fromTheme("camera-web"));
0133         action->setDisabled(true);
0134         connect(action, SIGNAL(triggered(bool)),
0135                 SLOT(onStartVideoChatTriggered()));
0136 
0137         if (index.data(KTp::ContactCanVideoCallRole).toBool()) {
0138             action->setEnabled(true);
0139         }
0140 
0141         action = menu->addAction(i18n("Send File..."));
0142         action->setIcon(QIcon::fromTheme("mail-attachment"));
0143         action->setDisabled(true);
0144         connect(action, SIGNAL(triggered(bool)),
0145                 SLOT(onStartFileTransferTriggered()));
0146 
0147         if (index.data(KTp::ContactCanFileTransferRole).toBool()) {
0148             action->setEnabled(true);
0149         }
0150 
0151         action = menu->addAction(i18n("Share my desktop..."));
0152         action->setIcon(QIcon::fromTheme("krfb"));
0153         action->setDisabled(true);
0154         connect(action, SIGNAL(triggered(bool)),
0155                 SLOT(onStartDesktopSharingTriggered()));
0156 
0157         if (index.data(KTp::ContactTubesRole).toStringList().contains(QLatin1String("rfb"))) {
0158             action->setEnabled(true);
0159         }
0160 
0161         action = menu->addAction(i18n("Open Log..."));
0162         action->setIcon(QIcon::fromTheme("documentation"));
0163         action->setDisabled(true);
0164         connect(action, SIGNAL(triggered(bool)),
0165                 SLOT(onOpenLogViewerTriggered()));
0166 
0167         KTp::LogEntity entity(Tp::HandleTypeContact, contact->id());
0168         if (KTp::LogManager::instance()->logsExist(account, entity)) {
0169             action->setEnabled(true);
0170         }
0171     }
0172 
0173     menu->addSeparator();
0174     action = menu->addAction(QIcon::fromTheme("dialog-information"), i18n("Configure Notifications..."));
0175     action->setEnabled(true);
0176     connect(action, SIGNAL(triggered()),
0177                            SLOT(onNotificationConfigureTriggered()));
0178 
0179     // add "goto" submenu for navigating to links the contact has in presence message
0180     // first check to see if there are any links in the contact's presence message
0181     QStringList contactLinks;
0182     QString presenceMsg = index.data(KTp::ContactPresenceMessageRole).toString();
0183     if (presenceMsg.isEmpty()) {
0184         contactLinks = QStringList();
0185     } else {
0186         KTp::TextUrlData urls = KTp::TextParser::instance()->extractUrlData(presenceMsg);
0187         contactLinks = urls.fixedUrls;
0188     }
0189 
0190     if (!contactLinks.empty()) {
0191         QMenu *subMenu = new QMenu(i18np("Presence message link", "Presence message links", contactLinks.count()));
0192 
0193         foreach(const QString &link, contactLinks) {
0194             action = subMenu->addAction(link);
0195             action->setData(link);
0196         }
0197         connect(subMenu, SIGNAL(triggered(QAction*)), this, SLOT(onOpenLinkTriggered(QAction*)));
0198         menu->addMenu(subMenu);
0199     }
0200 
0201     menu->addSeparator();
0202 
0203     Tp::ConnectionPtr accountConnection = account->connection();
0204     if (accountConnection.isNull()) {
0205         qWarning() << "Account connection is nulled.";
0206     }
0207 
0208     if (m_mainWidget->d_ptr->model->groupMode() == KTp::ContactsModel::GroupGrouping) {
0209         // remove contact from group action, must be QAction because menu->addAction returns QAction
0210         QAction *groupRemoveAction = menu->addAction(QIcon(), i18n("Remove Contact From This Group"));
0211         connect(groupRemoveAction, SIGNAL(triggered(bool)), this, SLOT(onRemoveContactFromGroupTriggered()));
0212 
0213         if (accountConnection.isNull()) {
0214             groupRemoveAction->setDisabled(true);
0215         } else if (accountConnection->actualFeatures().contains(Tp::Connection::FeatureRosterGroups)) {
0216             QMenu* groupAddMenu = menu->addMenu(i18n("Move to Group"));
0217 
0218             QStringList groupList;
0219             QList<Tp::AccountPtr> accounts = m_accountManager->allAccounts();
0220             foreach (const Tp::AccountPtr &account, accounts) {
0221                 if (!account->connection().isNull()) {
0222                     groupList.append(account->connection()->contactManager()->allKnownGroups());
0223                 }
0224             }
0225 
0226             groupList.removeDuplicates();
0227 
0228             QStringList currentGroups = contact->groups();
0229 
0230             foreach (const QString &group, currentGroups) {
0231                 groupList.removeAll(group);
0232             }
0233 
0234             connect(groupAddMenu->addAction(i18n("Create New Group...")), SIGNAL(triggered(bool)),
0235                     this, SLOT(onCreateNewGroupTriggered()));
0236 
0237             groupAddMenu->addSeparator();
0238 
0239             foreach (const QString &group, groupList) {
0240                 connect(groupAddMenu->addAction(group), SIGNAL(triggered(bool)),
0241                         SLOT(onAddContactToGroupTriggered()));
0242             }
0243         } else {
0244             qWarning() << "Unable to support Groups";
0245         }
0246     }
0247 
0248     menu->addSeparator();
0249 
0250     if (!contact.isNull()) {
0251         if (contact->manager()->canRequestPresenceSubscription()) {
0252             if (contact->subscriptionState() != Tp::Contact::PresenceStateYes) {
0253                 action = menu->addAction(i18n("Re-request Contact Authorization"));
0254                 connect(action, SIGNAL(triggered(bool)), SLOT(onRerequestAuthorization()));
0255             }
0256         }
0257         if (contact->manager()->canAuthorizePresencePublication()) {
0258             if (contact->publishState() != Tp::Contact::PresenceStateYes) {
0259                 action = menu->addAction(i18n("Resend Contact Authorization"));
0260                 connect(action, SIGNAL(triggered(bool)), SLOT(onResendAuthorization()));
0261             }
0262         }
0263 
0264         action = menu->addSeparator(); //prevent two seperators in a row
0265 
0266         if (contact->isBlocked()) {
0267             action = menu->addAction(i18n("Unblock Contact"));
0268             connect(action, SIGNAL(triggered(bool)), SLOT(onUnblockContactTriggered()));
0269             action->setEnabled(contact->manager()->canBlockContacts());
0270         } else {
0271             action = menu->addAction(i18n("Block Contact"));
0272             connect(action, SIGNAL(triggered(bool)), SLOT(onBlockContactTriggered()));
0273             action->setEnabled(contact->manager()->canBlockContacts());
0274         }
0275 
0276         // remove contact action, must be QAction because that's what menu->addAction returns
0277         //TODO find an "if canRemove"
0278         QAction *removeAction = menu->addAction(QIcon::fromTheme("list-remove-user"), i18n("Remove Contact..."));
0279         connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(onDeleteContactTriggered()));
0280 
0281         menu->addSeparator();
0282     }
0283 
0284     action = menu->addAction(i18n("Show Contact Information..."));
0285     action->setIcon(QIcon::fromTheme(""));
0286     connect(action, SIGNAL(triggered()), SLOT(onShowInfoTriggered()));
0287 
0288     return menu;
0289 }
0290 
0291 QMenu* ContextMenu::groupContextMenu(const QModelIndex &index)
0292 {
0293     if (!index.isValid()) {
0294         return 0;
0295     }
0296 
0297     m_currentIndex = index;
0298 
0299     const QString groupName = index.data(Qt::DisplayRole).toString();
0300 
0301     QMenu *menu = new QMenu();
0302     menu->setTitle(groupName);
0303 
0304     //must be QAction, because menu->addAction returns QAction, otherwise compilation dies horribly
0305     QAction *action = menu->addAction(i18n("Rename Group..."));
0306     action->setIcon(QIcon::fromTheme("edit-rename"));
0307 
0308     connect(action, SIGNAL(triggered(bool)),
0309             this, SLOT(onRenameGroupTriggered()));
0310 
0311     action = menu->addAction(i18n("Delete Group"));
0312     action->setIcon(QIcon::fromTheme("edit-delete"));
0313 
0314     connect(action, SIGNAL(triggered(bool)),
0315             this, SLOT(onDeleteGroupTriggered()));
0316 
0317     return menu;
0318 }
0319 
0320 void ContextMenu::onRemoveContactFromGroupTriggered()
0321 {
0322     if (m_currentIndex.parent().data(KTp::RowTypeRole).toUInt() != KTp::GroupRowType) {
0323         return;
0324     }
0325 
0326     const QString groupName = m_currentIndex.parent().data(Qt::DisplayRole).toString();
0327     Tp::ContactPtr contact =  m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0328 
0329     Tp::PendingOperation *operation = contact->removeFromGroup(groupName);
0330 
0331     if (operation) {
0332         connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0333                 m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0334     }
0335 }
0336 
0337 void ContextMenu::onOpenLinkTriggered(QAction *action)
0338 {
0339     QDesktopServices::openUrl(QUrl(action->data().toString()));
0340 }
0341 
0342 void ContextMenu::onShowInfoTriggered()
0343 {
0344     if (!m_currentIndex.isValid()) {
0345         qWarning() << "Invalid index provided.";
0346         return;
0347     }
0348 
0349     if (KTp::kpeopleEnabled()) {
0350     #ifdef HAVE_KPEOPLE
0351         QString personId = m_currentIndex.data(KTp::PersonIdRole).toString();
0352         if (!personId.isEmpty()) {
0353             KPeople::PersonDetailsDialog *view = new KPeople::PersonDetailsDialog(m_mainWidget);
0354             KPeople::PersonData *person = new KPeople::PersonData(personId, view);
0355             view->setPerson(person);
0356             view->setAttribute(Qt::WA_DeleteOnClose);
0357             view->show();
0358         }
0359     #endif
0360     } else {
0361         const Tp::AccountPtr &account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
0362         const Tp::ContactPtr &contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0363         if (account && contact) {
0364             KTp::ContactInfoDialog* contactInfoDialog = new KTp::ContactInfoDialog(account, contact, m_mainWidget);
0365             contactInfoDialog->setAttribute(Qt::WA_DeleteOnClose);
0366             contactInfoDialog->show();
0367         }
0368     }
0369 }
0370 
0371 void ContextMenu::onStartTextChatTriggered()
0372 {
0373     if (!m_currentIndex.isValid()) {
0374         qWarning() << "Invalid index provided.";
0375         return;
0376     }
0377 
0378     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0379     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
0380 
0381     if (contact && account) {
0382         m_mainWidget->startTextChannel(account, contact);
0383     }
0384 }
0385 
0386 void ContextMenu::onStartAudioChatTriggered()
0387 {
0388     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0389     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
0390 
0391     if (contact && account) {
0392         m_mainWidget->startAudioChannel(account, contact);
0393     }
0394 }
0395 
0396 void ContextMenu::onStartVideoChatTriggered()
0397 {
0398     if (!m_currentIndex.isValid()) {
0399         qWarning() << "Invalid index provided.";
0400         return;
0401     }
0402 
0403     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0404     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
0405 
0406     if (contact && account) {
0407         m_mainWidget->startVideoChannel(account, contact);
0408     }
0409 }
0410 
0411 void ContextMenu::onStartFileTransferTriggered()
0412 {
0413     if (!m_currentIndex.isValid()) {
0414         qWarning() << "Invalid index provided.";
0415         return;
0416     }
0417 
0418     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0419     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
0420 
0421     if (contact && account) {
0422         m_mainWidget->startFileTransferChannel(account, contact);
0423     }
0424 }
0425 
0426 void ContextMenu::onStartDesktopSharingTriggered()
0427 {
0428     if (!m_currentIndex.isValid()) {
0429         qWarning() << "Invalid index provided.";
0430         return;
0431     }
0432 
0433     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0434     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
0435 
0436     if (contact && account) {
0437         m_mainWidget->startDesktopSharing(account, contact);
0438     }
0439 }
0440 
0441 void ContextMenu::onOpenLogViewerTriggered()
0442 {
0443     if (!m_currentIndex.isValid()) {
0444       qWarning() << "Invalid index provided.";
0445       return;
0446     }
0447 
0448     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0449     Tp::AccountPtr account = m_currentIndex.data(KTp::AccountRole).value<Tp::AccountPtr>();
0450 
0451     if (contact && account) {
0452         m_mainWidget->startLogViewer(account, contact);
0453     }
0454 }
0455 
0456 void ContextMenu::onUnblockContactTriggered()
0457 {
0458     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0459 
0460     Tp::PendingOperation *operation = contact->unblock(); //FIXME
0461     connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0462             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0463 }
0464 
0465 void ContextMenu::onAddContactToGroupTriggered()
0466 {
0467     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0468 
0469     QAction *action = qobject_cast<QAction*>(sender());
0470     if (!action) {
0471         qWarning() << "Invalid action";
0472         return;
0473     }
0474 
0475     const QStringList currentGroups = contact->groups();
0476 
0477     Tp::PendingOperation* operation = contact->addToGroup(action->text().remove('&'));
0478 
0479     if (operation) {
0480         connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0481                 m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0482 
0483         foreach (const QString &group, currentGroups) {
0484             Tp::PendingOperation* operation = contact->removeFromGroup(group);
0485             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0486                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0487         }
0488     }
0489 }
0490 
0491 void ContextMenu::onCreateNewGroupTriggered()
0492 {
0493     bool ok = false;
0494 
0495     QString newGroupName = QInputDialog::getText(0, i18n("New Group Name"),
0496                                                  i18n("Please enter the new group name"),
0497                                                  QLineEdit::Normal,
0498                                                  QString(),
0499                                                  &ok);
0500 
0501     if (ok) {
0502         Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0503         Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
0504 
0505         connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0506                 m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0507     }
0508 }
0509 
0510 void ContextMenu::onRenameGroupTriggered()
0511 {
0512     if (m_currentIndex.data(KTp::RowTypeRole).toUInt() != KTp::GroupRowType) {
0513         return;
0514     }
0515 
0516     const QString groupName = m_currentIndex.data(Qt::DisplayRole).toString();
0517     const QAbstractItemModel *model = m_currentIndex.model();
0518 
0519     bool ok = false;
0520 
0521     QString newGroupName = QInputDialog::getText(0, i18n("New Group Name"),
0522                                                  i18n("Please enter the new group name"),
0523                                                  QLineEdit::Normal,
0524                                                  groupName,
0525                                                  &ok);
0526 
0527     if (ok && groupName != newGroupName) {
0528         //loop through all child indexes of m_currentIndex
0529         for(int i = 0; i < model->rowCount(m_currentIndex); i++) {
0530             Tp::ContactPtr contact = model->index(i, 0 , m_currentIndex).data(KTp::ContactRole).value<KTp::ContactPtr>();
0531             Q_ASSERT(contact);
0532 
0533             Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
0534             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0535                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0536 
0537             operation = contact->removeFromGroup(groupName);
0538             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0539                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0540         }
0541     }
0542 }
0543 
0544 void ContextMenu::onDeleteGroupTriggered()
0545 {
0546     if (m_accountManager.isNull() ||
0547         (m_currentIndex.data(KTp::RowTypeRole).toUInt() != KTp::GroupRowType)) {
0548         return;
0549     }
0550 
0551     const QString groupName = m_currentIndex.data(Qt::DisplayRole).toString();
0552     const QAbstractItemModel *model = m_currentIndex.model();
0553 
0554 
0555     if (KMessageBox::warningContinueCancel(m_mainWidget,
0556                                            i18n("Do you really want to remove group %1?\n\n"
0557                                                 "Note that all contacts will be moved to group 'Ungrouped'", groupName),
0558                                            i18n("Remove Group")) == KMessageBox::Continue) {
0559 
0560         for(int i = 0; i < model->rowCount(m_currentIndex); i++) {
0561             Tp::ContactPtr contact = model->index(i, 0 , m_currentIndex).data(KTp::ContactRole).value<KTp::ContactPtr>();
0562 
0563             Q_ASSERT(contact);
0564 
0565             Tp::PendingOperation *operation = contact->removeFromGroup(groupName);
0566             connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0567                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0568         }
0569 
0570         foreach (const Tp::AccountPtr &account, m_accountManager->allAccounts()) {
0571             if (account->connection()) {
0572                 Tp::PendingOperation *operation = account->connection()->contactManager()->removeGroup(groupName);
0573                 connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0574                         m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0575             }
0576         }
0577     }
0578 }
0579 
0580 void ContextMenu::onBlockContactTriggered()
0581 {
0582     Tp::ContactPtr contact =  m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0583 
0584     Tp::PendingOperation *operation = contact->block();
0585     connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
0586             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0587 }
0588 
0589 void ContextMenu::onDeleteContactTriggered()
0590 {
0591     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0592 
0593     QList<Tp::ContactPtr>contactList;
0594     contactList.append(contact);
0595 
0596     // ask for confirmation
0597     QPointer<RemoveContactDialog> removeDialog = new RemoveContactDialog(contact, m_mainWidget);
0598 
0599     if (removeDialog.data()->exec() == QDialog::Accepted) {
0600         if (!removeDialog.isNull()) {
0601             // remove from contact list
0602             Tp::PendingOperation *deleteOp = contact->manager()->removeContacts(contactList);
0603             connect(deleteOp, SIGNAL(finished(Tp::PendingOperation*)),
0604                     m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0605 
0606             if (removeDialog.data()->blockContact()) {
0607                 // block contact
0608                 Tp::PendingOperation *blockOp = contact->manager()->blockContacts(contactList);
0609                 connect(blockOp, SIGNAL(finished(Tp::PendingOperation*)),
0610                         m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0611             }
0612         }
0613     }
0614 
0615     delete removeDialog.data();
0616 }
0617 
0618 void ContextMenu::onRerequestAuthorization()
0619 {
0620     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0621     Tp::PendingOperation *op = contact->manager()->requestPresenceSubscription(QList<Tp::ContactPtr>() << contact);
0622     connect(op, SIGNAL(finished(Tp::PendingOperation*)),
0623             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0624 }
0625 
0626 void ContextMenu::onResendAuthorization()
0627 {
0628     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0629     Tp::PendingOperation *op = contact->manager()->authorizePresencePublication(QList<Tp::ContactPtr>() << contact);
0630     connect(op, SIGNAL(finished(Tp::PendingOperation*)),
0631             m_mainWidget, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
0632 }
0633 
0634 void ContextMenu::onNotificationConfigureTriggered()
0635 {
0636     Tp::ContactPtr contact = m_currentIndex.data(KTp::ContactRole).value<KTp::ContactPtr>();
0637 
0638     KTp::NotificationConfigDialog *notificationDialog = new KTp::NotificationConfigDialog(contact, m_mainWidget);
0639     notificationDialog->show();
0640 }