summaryrefslogtreecommitdiff
path: root/qt4/examples/roster/roster-widget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qt4/examples/roster/roster-widget.cpp')
-rw-r--r--qt4/examples/roster/roster-widget.cpp380
1 files changed, 380 insertions, 0 deletions
diff --git a/qt4/examples/roster/roster-widget.cpp b/qt4/examples/roster/roster-widget.cpp
new file mode 100644
index 000000000..21b7526f5
--- /dev/null
+++ b/qt4/examples/roster/roster-widget.cpp
@@ -0,0 +1,380 @@
+/**
+ * This file is part of TelepathyQt4
+ *
+ * @copyright Copyright (C) 2009-2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ * @license LGPL 2.1
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "roster-widget.h"
+#include "_gen/roster-widget.moc.hpp"
+
+#include "roster-item.h"
+
+#include <TelepathyQt4/Types>
+#include <TelepathyQt4/Contact>
+#include <TelepathyQt4/ContactManager>
+#include <TelepathyQt4/PendingConnection>
+#include <TelepathyQt4/PendingContacts>
+#include <TelepathyQt4/PendingOperation>
+#include <TelepathyQt4/PendingReady>
+
+#include <QAction>
+#include <QDebug>
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QMessageBox>
+#include <QPushButton>
+#include <QVBoxLayout>
+
+using namespace Tp;
+
+RosterWidget::RosterWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ setWindowTitle(QLatin1String("Roster"));
+
+ createActions();
+ setupGui();
+}
+
+RosterWidget::~RosterWidget()
+{
+}
+
+void RosterWidget::setConnection(const ConnectionPtr &conn)
+{
+ if (mConn) {
+ unsetConnection();
+ }
+
+ mConn = conn;
+ connect(conn->contactManager().data(),
+ SIGNAL(presencePublicationRequested(const Tp::Contacts &)),
+ SLOT(onPresencePublicationRequested(const Tp::Contacts &)));
+ // TODO listen to allKnownContactsChanged
+
+ connect(conn->contactManager().data(),
+ SIGNAL(stateChanged(Tp::ContactListState)),
+ SLOT(onContactManagerStateChanged(Tp::ContactListState)));
+ onContactManagerStateChanged(conn->contactManager()->state());
+}
+
+void RosterWidget::unsetConnection()
+{
+ while (mList->count() > 0) {
+ RosterItem *item = (RosterItem *) mList->item(0);
+ mList->takeItem(0);
+ delete item;
+ }
+ mConn.reset();
+ updateActions();
+ mAddBtn->setEnabled(false);
+}
+
+void RosterWidget::createActions()
+{
+ mAuthAction = new QAction(QLatin1String("Authorize Contact"), this);
+ mAuthAction->setEnabled(false);
+ connect(mAuthAction,
+ SIGNAL(triggered(bool)),
+ SLOT(onAuthActionTriggered(bool)));
+ mDenyAction = new QAction(QLatin1String("Deny Contact"), this);
+ mDenyAction->setEnabled(false);
+ connect(mDenyAction,
+ SIGNAL(triggered(bool)),
+ SLOT(onDenyActionTriggered(bool)));
+ mRemoveAction = new QAction(QLatin1String("Remove Contact"), this);
+ mRemoveAction->setEnabled(false);
+ connect(mRemoveAction,
+ SIGNAL(triggered(bool)),
+ SLOT(onRemoveActionTriggered(bool)));
+ mBlockAction = new QAction(QLatin1String("Block Contact"), this);
+ mBlockAction->setEnabled(false);
+ mBlockAction->setCheckable(true);
+ connect(mBlockAction,
+ SIGNAL(triggered(bool)),
+ SLOT(onBlockActionTriggered(bool)));
+}
+
+void RosterWidget::setupGui()
+{
+ QVBoxLayout *vbox = new QVBoxLayout;
+
+ mList = new QListWidget;
+ connect(mList,
+ SIGNAL(itemSelectionChanged()),
+ SLOT(onItemSelectionChanged()));
+ vbox->addWidget(mList);
+
+ mList->setContextMenuPolicy(Qt::ActionsContextMenu);
+ mList->addAction(mAuthAction);
+ mList->addAction(mDenyAction);
+ mList->addAction(mRemoveAction);
+ mList->addAction(mBlockAction);
+
+ QHBoxLayout *hbox = new QHBoxLayout;
+
+ mAddBtn = new QPushButton(QLatin1String("+"));
+ mAddBtn->setEnabled(false);
+ connect(mAddBtn,
+ SIGNAL(clicked(bool)),
+ SLOT(onAddButtonClicked()));
+ hbox->addWidget(mAddBtn);
+ hbox->addStretch(1);
+
+ vbox->addLayout(hbox);
+
+ setLayout(vbox);
+
+ mAddDlg = new QDialog(this);
+ mAddDlg->setWindowTitle(QLatin1String("Add Contact"));
+ QVBoxLayout *addDlgVBox = new QVBoxLayout;
+
+ QHBoxLayout *addDlgEntryHBox = new QHBoxLayout;
+ QLabel *label = new QLabel(QLatin1String("Username"));
+ addDlgEntryHBox->addWidget(label);
+ mAddDlgEdt = new QLineEdit();
+ addDlgEntryHBox->addWidget(mAddDlgEdt);
+ addDlgVBox->addLayout(addDlgEntryHBox);
+
+ QDialogButtonBox *addDlgBtnBox = new QDialogButtonBox(
+ QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
+ connect(addDlgBtnBox, SIGNAL(accepted()), mAddDlg, SLOT(accept()));
+ connect(addDlgBtnBox, SIGNAL(rejected()), mAddDlg, SLOT(reject()));
+ addDlgVBox->addWidget(addDlgBtnBox);
+
+ mAddDlg->setLayout(addDlgVBox);
+}
+
+RosterItem *RosterWidget::createItemForContact(const ContactPtr &contact,
+ bool &exists)
+{
+ RosterItem *item;
+ exists = false;
+ for (int i = 0; i < mList->count(); ++i) {
+ item = dynamic_cast<RosterItem*>(mList->item(i));
+ if (item->contact() == contact) {
+ exists = true;
+ return item;
+ }
+ }
+
+ return new RosterItem(contact, mList);
+}
+
+void RosterWidget::onContactManagerStateChanged(ContactListState state)
+{
+ if (state == ContactListStateSuccess) {
+ qDebug() << "Loading contacts";
+ RosterItem *item;
+ bool exists;
+ foreach (const ContactPtr &contact, mConn->contactManager()->allKnownContacts()) {
+ exists = false;
+ item = createItemForContact(contact, exists);
+ if (!exists) {
+ connect(item, SIGNAL(changed()), SLOT(updateActions()));
+ }
+ }
+
+ mAddBtn->setEnabled(true);
+ }
+}
+
+void RosterWidget::onPresencePublicationRequested(const Contacts &contacts)
+{
+ qDebug() << "Presence publication requested";
+ RosterItem *item;
+ bool exists;
+ foreach (const ContactPtr &contact, contacts) {
+ exists = false;
+ item = createItemForContact(contact, exists);
+ if (!exists) {
+ connect(item, SIGNAL(changed()), SLOT(updateActions()));
+ }
+ }
+}
+
+void RosterWidget::onItemSelectionChanged()
+{
+ updateActions();
+}
+
+void RosterWidget::onAddButtonClicked()
+{
+ mAddDlgEdt->clear();
+ int ret = mAddDlg->exec();
+ if (ret == QDialog::Rejected) {
+ return;
+ }
+
+ QString username = mAddDlgEdt->text();
+ PendingContacts *pcontacts = mConn->contactManager()->contactsForIdentifiers(
+ QStringList() << username);
+ connect(pcontacts,
+ SIGNAL(finished(Tp::PendingOperation *)),
+ SLOT(onContactRetrieved(Tp::PendingOperation *)));
+}
+
+void RosterWidget::onAuthActionTriggered(bool checked)
+{
+ Q_UNUSED(checked);
+
+ QList<QListWidgetItem *> selectedItems = mList->selectedItems();
+ if (selectedItems.isEmpty()) {
+ return;
+ }
+
+ Q_ASSERT(selectedItems.size() == 1);
+ RosterItem *item = dynamic_cast<RosterItem*>(selectedItems.first());
+ if (item->contact()->publishState() != Contact::PresenceStateYes) {
+ item->contact()->authorizePresencePublication();
+ }
+}
+
+void RosterWidget::onDenyActionTriggered(bool checked)
+{
+ Q_UNUSED(checked);
+
+ QList<QListWidgetItem *> selectedItems = mList->selectedItems();
+ if (selectedItems.isEmpty()) {
+ return;
+ }
+
+ Q_ASSERT(selectedItems.size() == 1);
+ RosterItem *item = dynamic_cast<RosterItem*>(selectedItems.first());
+ if (item->contact()->publishState() != Contact::PresenceStateNo) {
+ // The contact can't see my presence
+ item->contact()->removePresencePublication();
+ }
+}
+
+void RosterWidget::onRemoveActionTriggered(bool checked)
+{
+ Q_UNUSED(checked);
+
+ QList<QListWidgetItem *> selectedItems = mList->selectedItems();
+ if (selectedItems.isEmpty()) {
+ return;
+ }
+
+ Q_ASSERT(selectedItems.size() == 1);
+ RosterItem *item = dynamic_cast<RosterItem*>(selectedItems.first());
+ if (item->contact()->subscriptionState() != Contact::PresenceStateNo) {
+ // The contact can't see my presence and I can't see his/her presence
+ item->contact()->removePresencePublication();
+ item->contact()->removePresenceSubscription();
+ }
+}
+
+void RosterWidget::onBlockActionTriggered(bool checked)
+{
+ QList<QListWidgetItem *> selectedItems = mList->selectedItems();
+ if (selectedItems.isEmpty()) {
+ return;
+ }
+
+ Q_ASSERT(selectedItems.size() == 1);
+ RosterItem *item = dynamic_cast<RosterItem*>(selectedItems.first());
+ if (checked) {
+ item->contact()->block();
+ } else {
+ item->contact()->unblock();
+ }
+}
+
+void RosterWidget::onContactRetrieved(Tp::PendingOperation *op)
+{
+ PendingContacts *pcontacts = qobject_cast<PendingContacts *>(op);
+ QList<ContactPtr> contacts = pcontacts->contacts();
+ Q_ASSERT(pcontacts->identifiers().size() == 1);
+ QString username = pcontacts->identifiers().first();
+ if (contacts.size() != 1 || !contacts.first()) {
+ QMessageBox msgBox;
+ msgBox.setText(QString(QLatin1String("Unable to add contact \"%1\"")).arg(username));
+ msgBox.exec();
+ return;
+ }
+
+ ContactPtr contact = contacts.first();
+ qDebug() << "Request presence subscription for contact" << username;
+ bool exists = false;
+ RosterItem *item = createItemForContact(contact, exists);
+ if (!exists) {
+ connect(item, SIGNAL(changed()), SLOT(updateActions()));
+ }
+ contact->requestPresenceSubscription();
+}
+
+void RosterWidget::updateActions()
+{
+ QList<QListWidgetItem *> selectedItems = mList->selectedItems();
+ if (selectedItems.isEmpty()) {
+ mAuthAction->setEnabled(false);
+ mDenyAction->setEnabled(false);
+ mRemoveAction->setEnabled(false);
+ mBlockAction->setEnabled(false);
+ updateActions(0);
+ return;
+ }
+ Q_ASSERT(selectedItems.size() == 1);
+
+ RosterItem *item = dynamic_cast<RosterItem*>(selectedItems.first());
+ ContactPtr contact = item->contact();
+
+ ContactManagerPtr manager = contact->manager();
+ qDebug() << "Contact" << contact->id() << "selected";
+ qDebug() << " subscription state:" << contact->subscriptionState();
+ qDebug() << " publish state :" << contact->publishState();
+ qDebug() << " blocked :" << contact->isBlocked();
+
+ if (manager->canAuthorizePresencePublication() &&
+ contact->publishState() == Contact::PresenceStateAsk) {
+ mAuthAction->setEnabled(true);
+ } else {
+ mAuthAction->setEnabled(false);
+ }
+
+ if (manager->canRemovePresencePublication() &&
+ contact->publishState() != Contact::PresenceStateNo) {
+ mDenyAction->setEnabled(true);
+ } else {
+ mDenyAction->setEnabled(false);
+ }
+
+ if (manager->canRemovePresenceSubscription() &&
+ contact->subscriptionState() != Contact::PresenceStateNo) {
+ mRemoveAction->setEnabled(true);
+ } else {
+ mRemoveAction->setEnabled(false);
+ }
+
+ if (manager->canBlockContacts() &&
+ contact->publishState() == Contact::PresenceStateYes) {
+ mBlockAction->setEnabled(true);
+ } else {
+ mBlockAction->setEnabled(false);
+ }
+
+ mBlockAction->setChecked(contact->isBlocked());
+
+ updateActions(item);
+}