[SCM] ktp-contact-list packaging branch, master, updated. debian/15.12.1-2-1070-g6c56f91

Maximiliano Curia maxy at moszumanska.debian.org
Sat May 28 00:08:20 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-contact-list.git;a=commitdiff;h=32cdb44

The following commit has been merged in the master branch:
commit 32cdb447b3f61bb925e7b6670f2a8da434678895
Author: Martin Klapetek <martin.klapetek at gmail.com>
Date:   Tue Dec 20 13:10:54 2011 +0100

    Put the context menu logic to a separate class
    
    Reviewed-by: George Kiagiadakis
    REVIEW: 103477
---
 CMakeLists.txt   |   1 +
 context-menu.cpp | 501 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 context-menu.h   |  68 ++++++++
 main-widget.cpp  | 475 +---------------------------------------------------
 main-widget.h    |  28 +---
 5 files changed, 581 insertions(+), 492 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5067b8b..e6d7cea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,6 +24,7 @@ include_directories (${KDE4_INCLUDES}
 
 
 set (contactlist_SRCS
+     context-menu.cpp
      avatar-button.cpp
      abstract-contact-delegate.cpp
      contact-list-application.cpp
diff --git a/context-menu.cpp b/context-menu.cpp
new file mode 100644
index 0000000..fff8c7a
--- /dev/null
+++ b/context-menu.cpp
@@ -0,0 +1,501 @@
+/*
+    Contact list context menu
+    Copyright (C) 2011  Martin Klapetek <martin.klapetek at gmail.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "context-menu.h"
+
+#include <KDebug>
+
+#include <KMenu>
+#include <KLocalizedString>
+#include <KIcon>
+#include <KToolInvocation>
+#include <KInputDialog>
+#include <KMessageBox>
+
+#include <KTelepathy/Models/accounts-model.h>
+#include <KTelepathy/Models/contact-model-item.h>
+#include <KTelepathy/Models/proxy-tree-node.h>
+#include <KTelepathy/Models/groups-model-item.h>
+#include <KTelepathy/Models/groups-model.h>
+#include <KTelepathy/text-parser.h>
+
+#include <TelepathyQt/ContactManager>
+
+#include "dialogs/remove-contact-dialog.h"
+#include "dialogs/contact-info.h"
+
+ContextMenu::ContextMenu(MainWidget *mainWidget)
+    : QObject(mainWidget)
+{
+    m_mainWidget = mainWidget;
+}
+
+
+ContextMenu::~ContextMenu()
+{
+
+}
+
+KMenu* ContextMenu::contactContextMenu(const QModelIndex &index)
+{
+    if (!index.isValid()) {
+        return 0;
+    }
+
+    m_currentIndex = index;
+
+    Tp::ContactPtr contact = index.data(AccountsModel::ItemRole).value<ContactModelItem*>()->contact();
+
+    if (contact.isNull()) {
+        kDebug() << "Contact is nulled";
+        return 0;
+    }
+
+    Tp::AccountPtr account = m_mainWidget->m_model->accountForContactItem(index.data(AccountsModel::ItemRole).value<ContactModelItem*>());
+
+    if (account.isNull()) {
+        kDebug() << "Account is nulled";
+        return 0;
+    }
+
+    KMenu *menu = new KMenu();
+    menu->addTitle(contact->alias());
+
+    //must be a QAction because menu->addAction returns QAction, breaks compilation otherwise
+    QAction *action = menu->addAction(i18n("Start Chat..."));
+    action->setIcon(KIcon("text-x-generic"));
+    action->setDisabled(true);
+    connect(action, SIGNAL(triggered(bool)),
+            SLOT(onStartTextChatTriggered()));
+
+    if (index.data(AccountsModel::TextChatCapabilityRole).toBool()) {
+        action->setEnabled(true);
+    }
+
+    Tp::ConnectionPtr accountConnection = account->connection();
+    if (accountConnection.isNull()) {
+        kDebug() << "Account connection is nulled.";
+        return 0;
+    }
+
+    action = menu->addAction(i18n("Start Audio Call..."));
+    action->setIcon(KIcon("voicecall"));
+    action->setDisabled(true);
+    connect(action, SIGNAL(triggered(bool)),
+            SLOT(onStartAudioChatTriggered()));
+
+    if (index.data(AccountsModel::AudioCallCapabilityRole).toBool()) {
+        action->setEnabled(true);
+    }
+
+    action = menu->addAction(i18n("Start Video Call..."));
+    action->setIcon(KIcon("webcamsend"));
+    action->setDisabled(true);
+    connect(action, SIGNAL(triggered(bool)),
+            SLOT(onStartVideoChatTriggered()));
+
+    if (index.data(AccountsModel::VideoCallCapabilityRole).toBool()) {
+        action->setEnabled(true);
+    }
+
+    action = menu->addAction(i18n("Send File..."));
+    action->setIcon(KIcon("mail-attachment"));
+    action->setDisabled(true);
+    connect(action, SIGNAL(triggered(bool)),
+            SLOT(onStartFileTransferTriggered()));
+
+    if (index.data(AccountsModel::FileTransferCapabilityRole).toBool()) {
+        action->setEnabled(true);
+    }
+
+    action = menu->addAction(i18n("Share my desktop..."));
+    action->setIcon(KIcon("krfb"));
+    action->setDisabled(true);
+    connect(action, SIGNAL(triggered(bool)),
+            SLOT(onStartDesktopSharingTriggered()));
+
+    if (index.data(AccountsModel::DesktopSharingCapabilityRole).toBool()) {
+        action->setEnabled(true);
+    }
+
+    // add "goto" submenu for navigating to links the contact has in presence message
+    // first check to see if there are any links in the contact's presence message
+    QStringList contactLinks;
+    QString presenceMsg = index.data(AccountsModel::PresenceMessageRole).toString();
+    if (presenceMsg.isEmpty()) {
+        contactLinks = QStringList();
+    } else {
+        KTp::TextUrlData urls = KTp::TextParser::instance()->extractUrlData(presenceMsg);
+        contactLinks = urls.fixedUrls;
+    }
+
+    if (!contactLinks.empty()) {
+        KMenu *subMenu = new KMenu(i18np("Presence message link", "Presence message links", contactLinks.count()));
+
+        foreach(const QString &link, contactLinks) {
+            action = subMenu->addAction(link);
+            action->setData(link);
+        }
+        connect(subMenu, SIGNAL(triggered(QAction*)), this, SLOT(onOpenLinkTriggered(QAction*)));
+        menu->addMenu(subMenu);
+    }
+
+    menu->addSeparator();
+
+    if (m_mainWidget->m_groupContactsAction->isChecked()) {
+        // remove contact from group action, must be QAction because menu->addAction returns QAction
+        QAction *groupRemoveAction = menu->addAction(KIcon(), i18n("Remove Contact From This Group"));
+        connect(groupRemoveAction, SIGNAL(triggered(bool)), this, SLOT(onRemoveContactFromGroupTriggered()));
+
+        if (accountConnection->actualFeatures().contains(Tp::Connection::FeatureRosterGroups)) {
+            QMenu* groupAddMenu = menu->addMenu(i18n("Move to Group"));
+
+            QStringList groupList;
+            QList<Tp::AccountPtr> accounts = m_mainWidget->m_accountManager->allAccounts();
+            foreach (const Tp::AccountPtr &account, accounts) {
+                if (!account->connection().isNull()) {
+                    groupList.append(account->connection()->contactManager()->allKnownGroups());
+                }
+            }
+
+            groupList.removeDuplicates();
+
+            QStringList currentGroups = contact->groups();
+
+            foreach (const QString &group, currentGroups) {
+                groupList.removeAll(group);
+            }
+
+            connect(groupAddMenu->addAction(i18n("Create New Group...")), SIGNAL(triggered(bool)),
+                    this, SLOT(onCreateNewGroupTriggered()));
+
+            groupAddMenu->addSeparator();
+
+            foreach (const QString &group, groupList) {
+                connect(groupAddMenu->addAction(group), SIGNAL(triggered(bool)),
+                        SLOT(onAddContactToGroupTriggered()));
+            }
+        } else {
+            kDebug() << "Unable to support Groups";
+        }
+
+        menu->addSeparator();
+    }
+
+    if (contact->isBlocked()) {
+        action = menu->addAction(i18n("Unblock Contact"));
+        connect(action, SIGNAL(triggered(bool)), SLOT(onUnblockContactTriggered()));
+    } else {
+        action = menu->addAction(i18n("Block Contact"));
+        connect(action, SIGNAL(triggered(bool)), SLOT(onBlockContactTriggered()));
+    }
+
+    // remove contact action, must be QAction because that's what menu->addAction returns
+    QAction *removeAction = menu->addAction(KIcon("list-remove-user"), i18n("Remove Contact"));
+    connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(onDeleteContactTriggered()));
+
+    menu->addSeparator();
+
+    action = menu->addAction(i18n("Show Info..."));
+    action->setIcon(KIcon(""));
+    connect(action, SIGNAL(triggered()), SLOT(onShowInfoTriggered()));
+
+    return menu;
+}
+
+KMenu* ContextMenu::groupContextMenu(const QModelIndex &index)
+{
+    if (!index.isValid()) {
+        return 0;
+    }
+
+    m_currentIndex = index;
+
+    GroupsModelItem *groupItem = index.data(AccountsModel::ItemRole).value<GroupsModelItem*>();
+
+    Q_ASSERT(groupItem);
+
+    KMenu *menu = new KMenu();
+    menu->addTitle(groupItem->groupName());
+
+    //must be QAction, because menu->addAction returns QAction, otherwise compilation dies horribly
+    QAction *action = menu->addAction(i18n("Rename Group..."));
+    action->setIcon(KIcon("edit-rename"));
+
+    connect(action, SIGNAL(triggered(bool)),
+            this, SLOT(onRenameGroup()));
+
+    action = menu->addAction(i18n("Delete Group"));
+    action->setIcon(KIcon("edit-delete"));
+
+    connect(action, SIGNAL(triggered(bool)),
+            this, SLOT(onDeleteGroup()));
+
+    return menu;
+}
+
+void ContextMenu::onRemoveContactFromGroupTriggered()
+{
+    QString groupName = m_currentIndex.parent().data(GroupsModel::GroupNameRole).toString();
+    ContactModelItem *contactItem = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+
+    Q_ASSERT(contactItem);
+    Tp::ContactPtr contact =  contactItem->contact();
+
+    Tp::PendingOperation* operation = contact->removeFromGroup(groupName);
+
+    if (operation) {
+        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+                m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+    }
+}
+
+void ContextMenu::onOpenLinkTriggered(QAction *action)
+{
+    KToolInvocation::invokeBrowser(action->data().toString());
+}
+
+void ContextMenu::onShowInfoTriggered()
+{
+    if (!m_currentIndex.isValid()) {
+        kDebug() << "Invalid index provided.";
+        return;
+    }
+
+    ContactModelItem* item = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+    if (item) {
+        ContactInfo contactInfoDialog(item->contact(), m_mainWidget);
+        contactInfoDialog.exec();
+    }
+}
+
+void ContextMenu::onStartTextChatTriggered()
+{
+    if (!m_currentIndex.isValid()) {
+        kDebug() << "Invalid index provided.";
+        return;
+    }
+
+    ContactModelItem* item = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+    if (item) {
+        m_mainWidget->startTextChannel(item);
+    }
+}
+
+void ContextMenu::onStartAudioChatTriggered()
+{
+    if (!m_currentIndex.isValid()) {
+        kDebug() << "Invalid index provided.";
+        return;
+    }
+
+    ContactModelItem* item = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+    if (item) {
+        m_mainWidget->startAudioChannel(item);
+    }
+}
+
+void ContextMenu::onStartVideoChatTriggered()
+{
+    if (!m_currentIndex.isValid()) {
+        kDebug() << "Invalid index provided.";
+        return;
+    }
+
+    ContactModelItem* item = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+    if (item) {
+        m_mainWidget->startVideoChannel(item);
+    }
+}
+
+void ContextMenu::onStartFileTransferTriggered()
+{
+    if (!m_currentIndex.isValid()) {
+        kDebug() << "Invalid index provided.";
+        return;
+    }
+
+    ContactModelItem* item = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+    if (item) {
+        m_mainWidget->startFileTransferChannel(item);
+    }
+}
+
+void ContextMenu::onStartDesktopSharingTriggered()
+{
+    if (!m_currentIndex.isValid()) {
+        kDebug() << "Invalid index provided.";
+        return;
+    }
+
+    ContactModelItem* item = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+    if (item) {
+        m_mainWidget->startDesktopSharing(item);
+    }
+}
+
+void ContextMenu::onUnblockContactTriggered()
+{
+    ContactModelItem* item = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+    Q_ASSERT(item);
+
+    Tp::ContactPtr contact = item->contact();
+
+    Tp::PendingOperation *operation = contact->unblock(); //FIXME
+    connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+            m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+}
+
+void ContextMenu::onAddContactToGroupTriggered()
+{
+    ContactModelItem* contactItem = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+
+    Q_ASSERT(contactItem);
+    Tp::ContactPtr contact =  contactItem->contact();
+
+    QAction *action = qobject_cast<QAction*>(sender());
+    if (!action) {
+        kDebug() << "Invalid action";
+        return;
+    }
+
+    const QStringList currentGroups = contact->groups();
+
+    Tp::PendingOperation* operation = contact->addToGroup(action->text().remove('&'));
+
+    if (operation) {
+        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+                m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+
+        foreach (const QString &group, currentGroups) {
+            Tp::PendingOperation* operation = contact->removeFromGroup(group);
+            connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+                    m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+        }
+    }
+}
+
+void ContextMenu::onCreateNewGroupTriggered()
+{
+    QString newGroupName = KInputDialog::getText(i18n("New Group Name"), i18n("Please enter the new group name"));
+
+    ContactModelItem *contactItem = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+
+    Q_ASSERT(contactItem);
+    Tp::ContactPtr contact =  contactItem->contact();
+    Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
+
+    connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+            m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+}
+
+void ContextMenu::onRenameGroupTriggered()
+{
+    GroupsModelItem *groupItem = m_currentIndex.data(AccountsModel::ItemRole).value<GroupsModelItem*>();
+
+    Q_ASSERT(groupItem);
+
+    QString newGroupName = KInputDialog::getText(i18n("New Group Name"), i18n("Please enter the new group name"), groupItem->groupName());
+
+    for(int i = 0; i < groupItem->size(); i++) {
+        Tp::ContactPtr contact = qobject_cast<ProxyTreeNode*>(groupItem->childAt(i))->data(AccountsModel::ItemRole).value<ContactModelItem*>()->contact();
+        Q_ASSERT(contact);
+
+        Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
+        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+                m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+
+        operation = contact->removeFromGroup(groupItem->groupName());
+        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+                m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+    }
+}
+
+void ContextMenu::onDeleteGroupTriggered()
+{
+    GroupsModelItem *groupItem = m_currentIndex.data(AccountsModel::ItemRole).value<GroupsModelItem*>();
+
+    if (KMessageBox::warningContinueCancel(m_mainWidget,
+                                           i18n("Do you really want to remove group %1?

"
+                                                "Note that all contacts will be moved to group 'Ungrouped'", groupItem->groupName()),
+                                           i18n("Remove Group")) == KMessageBox::Continue) {
+
+        for(int i = 0; i < groupItem->size(); i++) {
+            Tp::ContactPtr contact = qobject_cast<ProxyTreeNode*>(groupItem->childAt(i))->data(AccountsModel::ItemRole).value<ContactModelItem*>()->contact();
+
+            Q_ASSERT(contact);
+
+            Tp::PendingOperation *operation = contact->removeFromGroup(groupItem->groupName());
+            connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+                    m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+        }
+
+        foreach (const Tp::AccountPtr &account, m_mainWidget->m_accountManager->allAccounts()) {
+            if (account->connection()) {
+                Tp::PendingOperation *operation = account->connection()->contactManager()->removeGroup(groupItem->groupName());
+                connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+                        m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+            }
+        }
+    }
+}
+
+void ContextMenu::onBlockContactTriggered()
+{
+    ContactModelItem *contactItem = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+
+    Q_ASSERT(contactItem);
+    Tp::ContactPtr contact =  contactItem->contact();
+
+    Tp::PendingOperation *operation = contact->block();
+    connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
+            m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+}
+
+void ContextMenu::onDeleteContactTriggered()
+{
+    ContactModelItem* contactItem = m_currentIndex.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+
+    Q_ASSERT(contactItem);
+    Tp::ContactPtr contact =  contactItem->contact();
+
+    QList<Tp::ContactPtr>contactList;
+    contactList.append(contact);
+
+    // ask for confirmation
+    QWeakPointer<RemoveContactDialog> removeDialog = new RemoveContactDialog(contact, m_mainWidget);
+
+    if (removeDialog.data()->exec() == QDialog::Accepted) {
+        if (!removeDialog.isNull()) {
+            // remove from contact list
+            Tp::PendingOperation *deleteOp = contact->manager()->removeContacts(contactList);
+            connect(deleteOp, SIGNAL(finished(Tp::PendingOperation*)),
+                    m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+
+            if (removeDialog.data()->blockContact()) {
+                // block contact
+                Tp::PendingOperation *blockOp = contact->manager()->blockContacts(contactList);
+                connect(blockOp, SIGNAL(finished(Tp::PendingOperation*)),
+                        m_mainWidget, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
+            }
+        }
+    }
+
+    delete removeDialog.data();
+}
\ No newline at end of file
diff --git a/context-menu.h b/context-menu.h
new file mode 100644
index 0000000..178cdf0
--- /dev/null
+++ b/context-menu.h
@@ -0,0 +1,68 @@
+/*
+    Contact list context menu
+    Copyright (C) 2011  Martin Klapetek <martin.klapetek at gmail.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef CONTEXT_MENU_H
+#define CONTEXT_MENU_H
+
+#include <QObject>
+#include <QModelIndex>
+#include <QStringList>
+
+#include "main-widget.h"
+
+class AccountsModel;
+class ContactModelItem;
+class KMenu;
+class QAction;
+
+class ContextMenu : public QObject
+{
+    Q_OBJECT
+public:
+    explicit ContextMenu(MainWidget *mainWidget);
+    virtual ~ContextMenu();
+
+    KMenu* groupContextMenu(const QModelIndex &index);
+    KMenu* contactContextMenu(const QModelIndex &index);
+
+private Q_SLOTS:
+    void onAddContactToGroupTriggered();
+    void onBlockContactTriggered();
+    void onStartTextChatTriggered();
+    void onStartAudioChatTriggered();
+    void onStartVideoChatTriggered();
+    void onStartFileTransferTriggered();
+    void onStartDesktopSharingTriggered();
+    void onUnblockContactTriggered();
+    void onRemoveContactFromGroupTriggered();
+    void onCreateNewGroupTriggered();
+    void onRenameGroupTriggered();
+    void onDeleteGroupTriggered();
+    void onShowInfoTriggered();
+    void onDeleteContactTriggered();
+    void onOpenLinkTriggered(QAction *action);      /** triggered from custom contact menu when user clicks contact link */
+
+private:
+    MainWidget         *m_mainWidget;
+    QModelIndex         m_currentIndex;
+};
+
+#endif // CONTEXT_MENU_H
+
+class QTreeView;
diff --git a/main-widget.cpp b/main-widget.cpp
index 1a91516..1d3e10c 100644
--- a/main-widget.cpp
+++ b/main-widget.cpp
@@ -54,8 +54,6 @@
 #include <KInputDialog>
 #include <KStandardShortcut>
 #include <KNotification>
-#include <KToolInvocation>
-#include <kservice.h>
 
 #include "ui_main-widget.h"
 #include "account-buttons-panel.h"
@@ -67,8 +65,6 @@
 
 #include "dialogs/add-contact-dialog.h"
 #include "dialogs/join-chat-room-dialog.h"
-#include "dialogs/remove-contact-dialog.h"
-#include "dialogs/contact-info.h"
 
 #include <KTelepathy/Models/groups-model.h>
 #include <KTelepathy/Models/contact-model-item.h>
@@ -80,6 +76,7 @@
 #include <KTelepathy/text-parser.h>
 
 #include "tooltips/tooltipmanager.h"
+#include "context-menu.h"
 
 #define PREFERRED_TEXTCHAT_HANDLER "org.freedesktop.Telepathy.Client.KDE.TextUi"
 #define PREFERRED_FILETRANSFER_HANDLER "org.freedesktop.Telepathy.Client.KDE.FileTransfer"
@@ -270,6 +267,8 @@ MainWidget::MainWidget(QWidget *parent)
     m_contactsListView->viewport()->setAcceptDrops(true);
     m_contactsListView->setDropIndicatorShown(true);
 
+    m_contextMenu = new ContextMenu(this);
+
     addOverlayButtons();
 
     emit enableOverlays(guiConfigGroup.readEntry("selected_delegate", "full") == QLatin1String("full"));
@@ -737,9 +736,9 @@ void MainWidget::onCustomContextMenuRequested(const QPoint &pos)
     KMenu *menu = 0;
 
     if (item.userType() == qMetaTypeId<ContactModelItem*>()) {
-        menu = contactContextMenu(index);
+        menu = m_contextMenu->contactContextMenu(index);
     } else if (item.userType() == qMetaTypeId<GroupsModelItem*>()) {
-        menu = groupContextMenu(index);
+        menu = m_contextMenu->groupContextMenu(index);
     }
 
     if (menu) {
@@ -748,192 +747,7 @@ void MainWidget::onCustomContextMenuRequested(const QPoint &pos)
     }
 }
 
-KMenu* MainWidget::contactContextMenu(const QModelIndex &index)
-{
-    if (!index.isValid()) {
-        return 0;
-    }
-
-    Tp::ContactPtr contact = index.data(AccountsModel::ItemRole).value<ContactModelItem*>()->contact();
-
-    if (contact.isNull()) {
-        kDebug() << "Contact is nulled";
-        return 0;
-    }
-
-    Tp::AccountPtr account = m_model->accountForContactItem(index.data(AccountsModel::ItemRole).value<ContactModelItem*>());
-
-    if (account.isNull()) {
-        kDebug() << "Account is nulled";
-        return 0;
-    }
-
-    KMenu *menu = new KMenu();
-    menu->addTitle(contact->alias());
-
-    //must be a QAction because menu->addAction returns QAction, breaks compilation otherwise
-    QAction* action = menu->addAction(i18n("Start Chat..."));
-    action->setIcon(KIcon("text-x-generic"));
-    action->setDisabled(true);
-    connect(action, SIGNAL(triggered(bool)),
-            SLOT(onStartTextChatTriggered()));
-
-    if (index.data(AccountsModel::TextChatCapabilityRole).toBool()) {
-        action->setEnabled(true);
-    }
-
-    Tp::ConnectionPtr accountConnection = account->connection();
-    if (accountConnection.isNull()) {
-        kDebug() << "Account connection is nulled.";
-        return 0;
-    }
-
-    action = menu->addAction(i18n("Start Audio Call..."));
-    action->setIcon(KIcon("voicecall"));
-    action->setDisabled(true);
-    connect(action, SIGNAL(triggered(bool)),
-            SLOT(onStartAudioChatTriggered()));
-
-    if (index.data(AccountsModel::AudioCallCapabilityRole).toBool()) {
-        action->setEnabled(true);
-    }
-
-    action = menu->addAction(i18n("Start Video Call..."));
-    action->setIcon(KIcon("webcamsend"));
-    action->setDisabled(true);
-    connect(action, SIGNAL(triggered(bool)),
-            SLOT(onStartVideoChatTriggered()));
-
-    if (index.data(AccountsModel::VideoCallCapabilityRole).toBool()) {
-        action->setEnabled(true);
-    }
-
-    action = menu->addAction(i18n("Send File..."));
-    action->setIcon(KIcon("mail-attachment"));
-    action->setDisabled(true);
-    connect(action, SIGNAL(triggered(bool)),
-            SLOT(onStartFileTransferTriggered()));
-
-    if (index.data(AccountsModel::FileTransferCapabilityRole).toBool()) {
-        action->setEnabled(true);
-    }
-
-    action = menu->addAction(i18n("Share my desktop..."));
-    action->setIcon(KIcon("krfb"));
-    action->setDisabled(true);
-    connect(action, SIGNAL(triggered(bool)),
-            SLOT(onStartDesktopSharingTriggered()));
-
-    if (index.data(AccountsModel::DesktopSharingCapabilityRole).toBool()) {
-        action->setEnabled(true);
-    }
-
-    // add "goto" submenu for navigating to links the contact has in presence message
-    // first check to see if there are any links in the contact's presence message
-    QStringList contactLinks = extractLinksFromIndex(index);
-
-    if (!contactLinks.empty()) {
-        KMenu *subMenu = new KMenu(i18np("Presence message link", "Presence message links", contactLinks.count()));
-
-        foreach(const QString &link, contactLinks) {
-            action = subMenu->addAction(link);
-            action->setData(link);
-        }
-        connect(subMenu, SIGNAL(triggered(QAction*)), this, SLOT(onOpenLinkTriggered(QAction*)));
-        menu->addMenu(subMenu);
-    }
-
-    menu->addSeparator();
-
-    if (m_groupContactsAction->isChecked()) {
-        // remove contact from group action, must be QAction because menu->addAction returns QAction
-        QAction *groupRemoveAction = menu->addAction(KIcon(), i18n("Remove Contact From This Group"));
-        connect(groupRemoveAction, SIGNAL(triggered(bool)), this, SLOT(onRemoveContactFromGroupTriggered()));
-
-        if (accountConnection->actualFeatures().contains(Tp::Connection::FeatureRosterGroups)) {
-            QMenu* groupAddMenu = menu->addMenu(i18n("Move to Group"));
-
-            QStringList groupList;
-            QList<Tp::AccountPtr> accounts = m_accountManager->allAccounts();
-            foreach (const Tp::AccountPtr &account, accounts) {
-                if (!account->connection().isNull()) {
-                    groupList.append(account->connection()->contactManager()->allKnownGroups());
-                }
-            }
-
-            groupList.removeDuplicates();
-
-            QStringList currentGroups = contact->groups();
-
-            foreach (const QString &group, currentGroups) {
-                groupList.removeAll(group);
-            }
-
-            connect(groupAddMenu->addAction(i18n("Create New Group...")), SIGNAL(triggered(bool)),
-                    this, SLOT(onCreateNewGroupTriggered()));
-
-            groupAddMenu->addSeparator();
-
-            foreach (const QString &group, groupList) {
-                connect(groupAddMenu->addAction(group), SIGNAL(triggered(bool)),
-                        SLOT(onAddContactToGroupTriggered()));
-            }
-        } else {
-            kDebug() << "Unable to support Groups";
-        }
-
-        menu->addSeparator();
-    }
-
-    if (contact->isBlocked()) {
-        action = menu->addAction(i18n("Unblock Contact"));
-        connect(action, SIGNAL(triggered(bool)), SLOT(onUnblockContactTriggered()));
-    } else {
-        action = menu->addAction(i18n("Block Contact"));
-        connect(action, SIGNAL(triggered(bool)), SLOT(onBlockContactTriggered()));
-    }
-
-    // remove contact action, must be QAction because that's what menu->addAction returns
-    QAction *removeAction = menu->addAction(KIcon("list-remove-user"), i18n("Remove Contact"));
-    connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(onDeleteContactTriggered()));
-
-    menu->addSeparator();
-
-    action = menu->addAction(i18n("Show Info..."));
-    action->setIcon(KIcon(""));
-    connect(action, SIGNAL(triggered()), SLOT(onShowInfoTriggered()));
-
-    return menu;
-}
-
-KMenu* MainWidget::groupContextMenu(const QModelIndex &index)
-{
-    if (!index.isValid()) {
-        return 0;
-    }
-
-    GroupsModelItem *groupItem = index.data(AccountsModel::ItemRole).value<GroupsModelItem*>();
-
-    Q_ASSERT(groupItem);
 
-    KMenu *menu = new KMenu();
-    menu->addTitle(groupItem->groupName());
-
-    //must be QAction, because menu->addAction returns QAction, otherwise compilation dies horribly
-    QAction *action = menu->addAction(i18n("Rename Group..."));
-    action->setIcon(KIcon("edit-rename"));
-
-    connect(action, SIGNAL(triggered(bool)),
-            this, SLOT(onRenameGroup()));
-
-    action = menu->addAction(i18n("Delete Group"));
-    action->setIcon(KIcon("edit-delete"));
-
-    connect(action, SIGNAL(triggered(bool)),
-            this, SLOT(onDeleteGroup()));
-
-    return menu;
-}
 
 void MainWidget::onFilterStringChanged(const QString &str)
 {
@@ -941,150 +755,6 @@ void MainWidget::onFilterStringChanged(const QString &str)
     m_modelFilter->setFilterString(str);
 }
 
-void MainWidget::onAddContactToGroupTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    ContactModelItem* contactItem = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-
-    Q_ASSERT(contactItem);
-    Tp::ContactPtr contact =  contactItem->contact();
-
-    QAction *action = qobject_cast<QAction*>(sender());
-    if (!action) {
-        kDebug() << "Invalid action";
-        return;
-    }
-
-    const QStringList currentGroups = contact->groups();
-
-    Tp::PendingOperation* operation = contact->addToGroup(action->text().remove('&'));
-
-    if (operation) {
-        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-                SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-
-        foreach (const QString &group, currentGroups) {
-            Tp::PendingOperation* operation = contact->removeFromGroup(group);
-            connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-                    SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-        }
-    }
-}
-
-void MainWidget::onCreateNewGroupTriggered()
-{
-    QString newGroupName = KInputDialog::getText(i18n("New Group Name"), i18n("Please enter the new group name"));
-
-    QModelIndex index = m_contactsListView->currentIndex();
-    ContactModelItem *contactItem = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-
-    Q_ASSERT(contactItem);
-    Tp::ContactPtr contact =  contactItem->contact();
-    Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
-
-    connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-            SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-}
-
-void MainWidget::onRenameGroupTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-
-    GroupsModelItem *groupItem = index.data(AccountsModel::ItemRole).value<GroupsModelItem*>();
-
-    Q_ASSERT(groupItem);
-
-    QString newGroupName = KInputDialog::getText(i18n("New Group Name"), i18n("Please enter the new group name"), groupItem->groupName());
-
-    for(int i = 0; i < groupItem->size(); i++) {
-        Tp::ContactPtr contact = qobject_cast<ProxyTreeNode*>(groupItem->childAt(i))
-                                                             ->data(AccountsModel::ItemRole).value<ContactModelItem*>()->contact();
-        Q_ASSERT(contact);
-
-        Tp::PendingOperation *operation = contact->addToGroup(newGroupName);
-        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-                SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-
-        operation = contact->removeFromGroup(groupItem->groupName());
-        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-                SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-    }
-}
-
-void MainWidget::onDeleteGroupTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-
-    GroupsModelItem *groupItem = index.data(AccountsModel::ItemRole).value<GroupsModelItem*>();
-
-    if (KMessageBox::warningContinueCancel(this,
-                                           i18n("Do you really want to remove group %1?

"
-                                                "Note that all contacts will be moved to group 'Ungrouped'", groupItem->groupName()),
-                                           i18n("Remove Group")) == KMessageBox::Continue) {
-
-        for(int i = 0; i < groupItem->size(); i++) {
-            Tp::ContactPtr contact = qobject_cast<ProxyTreeNode*>(groupItem->childAt(i))
-                                                                 ->data(AccountsModel::ItemRole).value<ContactModelItem*>()->contact();
-            Q_ASSERT(contact);
-
-            Tp::PendingOperation *operation = contact->removeFromGroup(groupItem->groupName());
-            connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-                    SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-        }
-
-        foreach (const Tp::AccountPtr &account, m_accountManager->allAccounts()) {
-            if (account->connection()) {
-                Tp::PendingOperation *operation = account->connection()->contactManager()->removeGroup(groupItem->groupName());
-                connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-                        SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-            }
-        }
-    }
-}
-
-
-void MainWidget::onBlockContactTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    ContactModelItem* contactItem = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-
-    Q_ASSERT(contactItem);
-    Tp::ContactPtr contact =  contactItem->contact();
-
-    Tp::PendingOperation *operation = contact->block();
-    connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-            SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-}
-
-void MainWidget::onDeleteContactTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    ContactModelItem* contactItem = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-
-    Q_ASSERT(contactItem);
-    Tp::ContactPtr contact =  contactItem->contact();
-
-    QList<Tp::ContactPtr>contactList;
-    contactList.append(contact);
-
-    // ask for confirmation
-    QWeakPointer<RemoveContactDialog> removeDialog = new RemoveContactDialog(contact, this);
-
-    if (removeDialog.data()->exec() == QDialog::Accepted) {
-        // remove from contact list
-        Tp::PendingOperation *deleteOp = contact->manager()->removeContacts(contactList);
-        connect(deleteOp, SIGNAL(finished(Tp::PendingOperation*)), this, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-
-        if (removeDialog.data()->blockContact()) {
-            // block contact
-            Tp::PendingOperation *blockOp = contact->manager()->blockContacts(contactList);
-            connect(blockOp, SIGNAL(finished(Tp::PendingOperation*)), this, SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-        }
-    }
-
-    delete removeDialog.data();
-}
-
 void MainWidget::onGenericOperationFinished(Tp::PendingOperation* operation)
 {
     if (operation->isError()) {
@@ -1093,113 +763,6 @@ void MainWidget::onGenericOperationFinished(Tp::PendingOperation* operation)
     }
 }
 
-void MainWidget::onOpenLinkTriggered(QAction *action)
-{
-    KToolInvocation::invokeBrowser(action->data().toString());
-}
-
-void MainWidget::onShowInfoTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    if (!index.isValid()) {
-        kDebug() << "Invalid index provided.";
-        return;
-    }
-
-    ContactModelItem* item = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-    if (item) {
-        showInfo(item);
-    }
-}
-
-void MainWidget::showInfo(ContactModelItem *contactItem)
-{
-    ContactInfo contactInfoDialog(contactItem->contact(), this);
-    contactInfoDialog.exec();
-}
-
-void MainWidget::onStartTextChatTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    if (!index.isValid()) {
-        kDebug() << "Invalid index provided.";
-        return;
-    }
-
-    ContactModelItem* item = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-    if (item) {
-        startTextChannel(item);
-    }
-}
-
-void MainWidget::onStartAudioChatTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    if (!index.isValid()) {
-        kDebug() << "Invalid index provided.";
-        return;
-    }
-
-    ContactModelItem* item = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-    if (item) {
-        startAudioChannel(item);
-    }
-}
-
-void MainWidget::onStartVideoChatTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    if (!index.isValid()) {
-        kDebug() << "Invalid index provided.";
-        return;
-    }
-    ContactModelItem* item = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-    if (item) {
-        startVideoChannel(item);
-    }
-}
-
-void MainWidget::onStartFileTransferTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    if (!index.isValid()) {
-        kDebug() << "Invalid index provided.";
-        return;
-    }
-
-    ContactModelItem* item = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-    if (item) {
-        startFileTransferChannel(item);
-    }
-}
-
-void MainWidget::onStartDesktopSharingTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    if (!index.isValid()) {
-        kDebug() << "Invalid index provided.";
-        return;
-    }
-
-    ContactModelItem* item = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-    if (item) {
-        startDesktopSharing(item);
-    }
-}
-
-void MainWidget::onUnblockContactTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    ContactModelItem* item = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-    Q_ASSERT(item);
-
-    Tp::ContactPtr contact = item->contact();
-
-    Tp::PendingOperation *operation = contact->unblock();
-    connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-            SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-}
-
 void MainWidget::showSettingsKCM()
 {
     KSettings::Dialog *dialog = new KSettings::Dialog(this);
@@ -1218,17 +781,6 @@ void MainWidget::showSettingsKCM()
     dialog->exec();
 }
 
-QStringList MainWidget::extractLinksFromIndex(const QModelIndex& index)
-{
-    QString presenceMsg = index.data(AccountsModel::PresenceMessageRole).toString();
-    if (presenceMsg.isEmpty()) {
-        return QStringList();
-    } else {
-        KTp::TextUrlData urls = KTp::TextParser::instance()->extractUrlData(presenceMsg);
-        return urls.fixedUrls;
-    }
-}
-
 ///Was moved to telepathy-kded-module
 // void MainWidget::handleConnectionError(const Tp::AccountPtr& account)
 // {
@@ -1419,21 +971,4 @@ void MainWidget::onUsePerAccountPresenceTriggered()
     configGroup.config()->sync();
 }
 
-void MainWidget::onRemoveContactFromGroupTriggered()
-{
-    QModelIndex index = m_contactsListView->currentIndex();
-    QString groupName = index.parent().data(GroupsModel::GroupNameRole).toString();
-    ContactModelItem* contactItem = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
-
-    Q_ASSERT(contactItem);
-    Tp::ContactPtr contact =  contactItem->contact();
-
-    Tp::PendingOperation* operation = contact->removeFromGroup(groupName);
-
-    if (operation) {
-        connect(operation, SIGNAL(finished(Tp::PendingOperation*)),
-                SLOT(onGenericOperationFinished(Tp::PendingOperation*)));
-    }
-}
-
 #include "main-widget.moc"
diff --git a/main-widget.h b/main-widget.h
index b700a59..f01b377 100644
--- a/main-widget.h
+++ b/main-widget.h
@@ -34,6 +34,7 @@
 #include <KDualAction>
 #include "ui_main-widget.h"
 
+class ContextMenu;
 class ContactDelegateCompact;
 class GroupsModel;
 class KMenu;
@@ -79,7 +80,6 @@ public Q_SLOTS:
     void toggleSearchWidget(bool show);
     void showSettingsKCM();
     void showMessageToUser(const QString &text, const SystemMessageType type);
-    void showInfo(ContactModelItem *contactItem);
     void startTextChannel(ContactModelItem *contactItem);
     void startFileTransferChannel(ContactModelItem *contactItem);
     void startAudioChannel(ContactModelItem *contactItem);
@@ -89,24 +89,9 @@ public Q_SLOTS:
     void goOffline();
 
 private Q_SLOTS:
-    void onAddContactToGroupTriggered();
-    void onBlockContactTriggered();
-    void onStartTextChatTriggered();
-    void onStartAudioChatTriggered();
-    void onStartVideoChatTriggered();
-    void onStartFileTransferTriggered();
-    void onStartDesktopSharingTriggered();
-    void onUnblockContactTriggered();
-    void onRemoveContactFromGroupTriggered();
-    void onCreateNewGroupTriggered();
-    void onRenameGroupTriggered();
-    void onDeleteGroupTriggered();
-    void onShowInfoTriggered();
-    void onDeleteContactTriggered();
-    void onJoinChatRoomRequested();         /** join chat room action is triggered */
     void onUseGlobalPresenceTriggered();
     void onUsePerAccountPresenceTriggered();
-
+    void onJoinChatRoomRequested();                 /** join chat room action is triggered */
     void onAccountManagerReady(Tp::PendingOperation *op);
     void onContactListClicked(const QModelIndex &index);
     void onContactListDoubleClicked(const QModelIndex &index);
@@ -119,7 +104,6 @@ private Q_SLOTS:
     void onNewGroupModelItemsInserted(const QModelIndex &index, int start, int end);
 
     void onGenericOperationFinished(Tp::PendingOperation *operation);   /** called when a Tp::PendingOperation finishes. Used to check for errors */
-    void onOpenLinkTriggered(QAction *action);                          /** triggered from custom contact menu when user clicks contact link */
     void groupContacts(bool enabled);
 
 Q_SIGNALS:
@@ -131,9 +115,6 @@ private:
     //void handleConnectionError(const Tp::AccountPtr &account);      /** handle connection errors for given account. This method provides visual notification */
     void closeEvent(QCloseEvent *e);
 
-    KMenu* contactContextMenu(const QModelIndex &index);
-    KMenu* groupContextMenu(const QModelIndex &index);
-
     AccountsModel          *m_model;
     GroupsModel            *m_groupsModel;
     AccountsFilterModel    *m_modelFilter;
@@ -146,7 +127,10 @@ private:
     KAction                *m_groupContactsAction;
     KAction                *m_showOfflineAction;
     KAction                *m_searchContactAction;
-    KDualAction                *m_sortByPresenceAction;
+    KDualAction            *m_sortByPresenceAction;
+
+    friend class ContextMenu;
+    ContextMenu            *m_contextMenu;
 };
 
 

-- 
ktp-contact-list packaging



More information about the pkg-kde-commits mailing list