/*
* This file is part of TelepathyQt4Yell Models
*
* Copyright (C) 2010 Collabora Ltd.
*
* 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
#include "TelepathyQt4Yell/Models/_gen/accounts-model-item.moc.hpp"
#include
#include
#include
#include
#include
namespace Tpy
{
struct TELEPATHY_QT4_YELL_MODELS_NO_EXPORT AccountsModelItem::Private
{
Private(const Tp::AccountPtr &account)
: mAccount(account)
{
}
void setStatus(const QString &value);
void setStatusMessage(const QString &value);
Tp::AccountPtr mAccount;
Tp::ContactManagerPtr mManager;
};
void AccountsModelItem::Private::setStatus(const QString &value)
{
Tp::Presence presence = mAccount->currentPresence().barePresence();
presence.setStatus(Tp::ConnectionPresenceTypeUnset, value, QString());
mAccount->setRequestedPresence(presence);
}
void AccountsModelItem::Private::setStatusMessage(const QString &value)
{
Tp::Presence presence = mAccount->currentPresence().barePresence();
presence.setStatus(Tp::ConnectionPresenceTypeUnset, QString(), value);
mAccount->setRequestedPresence(presence);
}
AccountsModelItem::AccountsModelItem(const Tp::AccountPtr &account)
: mPriv(new Private(account))
{
if (!mPriv->mAccount->connection().isNull()) {
// call the connection changed slot so that signals get connected
onConnectionChanged(mPriv->mAccount->connection());
}
connect(mPriv->mAccount.data(),
SIGNAL(removed()),
SLOT(onRemoved()));
connect(mPriv->mAccount.data(),
SIGNAL(serviceNameChanged(QString)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(profileChanged(Tp::ProfilePtr)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(iconNameChanged(QString)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(nicknameChanged(QString)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(normalizedNameChanged(QString)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(validityChanged(bool)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(stateChanged(bool)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(capabilitiesChanged(Tp::ConnectionCapabilities)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(connectsAutomaticallyPropertyChanged(bool)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(parametersChanged(QVariantMap)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(changingPresence(bool)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(automaticPresenceChanged(Tp::Presence)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(currentPresenceChanged(Tp::Presence)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(requestedPresenceChanged(Tp::Presence)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(onlinenessChanged(bool)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(avatarChanged(Tp::Avatar)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(onlinenessChanged(bool)),
SLOT(onChanged()));
connect(mPriv->mAccount.data(),
SIGNAL(connectionStatusChanged(Tp::ConnectionStatus)),
SLOT(onStatusChanged(Tp::ConnectionStatus)));
connect(mPriv->mAccount.data(),
SIGNAL(connectionChanged(Tp::ConnectionPtr)),
SLOT(onConnectionChanged(Tp::ConnectionPtr)));
}
AccountsModelItem::~AccountsModelItem()
{
delete mPriv;
}
QVariant AccountsModelItem::data(int role) const
{
switch (role) {
case AccountsModel::ItemRole:
return QVariant::fromValue(
const_cast(
static_cast(this)));
case AccountsModel::IdRole:
return mPriv->mAccount->uniqueIdentifier();
case AccountsModel::AvatarRole:
return AvatarImageProvider::urlFor(mPriv->mAccount);
case AccountsModel::ValidRole:
return mPriv->mAccount->isValid();
case AccountsModel::EnabledRole:
return mPriv->mAccount->isEnabled();
case AccountsModel::ConnectionManagerNameRole:
return mPriv->mAccount->cmName();
case AccountsModel::ProtocolNameRole:
return mPriv->mAccount->protocolName();
case AccountsModel::DisplayNameRole:
case Qt::DisplayRole:
return mPriv->mAccount->displayName();
case AccountsModel::IconRole:
return mPriv->mAccount->iconName();
case AccountsModel::NicknameRole:
return mPriv->mAccount->nickname();
case AccountsModel::ConnectsAutomaticallyRole:
return mPriv->mAccount->connectsAutomatically();
case AccountsModel::ChangingPresenceRole:
return mPriv->mAccount->isChangingPresence();
case AccountsModel::AutomaticPresenceRole:
return mPriv->mAccount->automaticPresence().status();
case AccountsModel::AutomaticPresenceTypeRole:
return mPriv->mAccount->automaticPresence().type();
case AccountsModel::AutomaticPresenceStatusMessageRole:
return mPriv->mAccount->automaticPresence().statusMessage();
case AccountsModel::CurrentPresenceRole:
return mPriv->mAccount->currentPresence().status();
case AccountsModel::CurrentPresenceTypeRole:
return mPriv->mAccount->currentPresence().type();
case AccountsModel::CurrentPresenceStatusMessageRole:
return mPriv->mAccount->currentPresence().statusMessage();
case AccountsModel::RequestedPresenceRole:
return mPriv->mAccount->requestedPresence().status();
case AccountsModel::RequestedPresenceTypeRole:
return mPriv->mAccount->requestedPresence().type();
case AccountsModel::RequestedPresenceStatusMessageRole:
return mPriv->mAccount->requestedPresence().statusMessage();
case AccountsModel::ConnectionStatusRole:
return mPriv->mAccount->connectionStatus();
case AccountsModel::ConnectionStatusReasonRole:
return mPriv->mAccount->connectionStatusReason();
case AccountsModel::ContactListStateRole: {
if (!mPriv->mManager.isNull()) {
return mPriv->mManager->state();
} else {
return Tp::ContactListStateNone;
}
}
default:
return QVariant();
}
}
bool AccountsModelItem::setData(int role, const QVariant &value)
{
switch (role) {
case AccountsModel::EnabledRole:
setEnabled(value.toBool());
return true;
case AccountsModel::RequestedPresenceRole:
mPriv->setStatus(value.toString());
return true;
case AccountsModel::RequestedPresenceStatusMessageRole:
mPriv->setStatusMessage(value.toString());
return true;
case AccountsModel::NicknameRole:
setNickname(value.toString());
return true;
default:
return false;
}
}
Tp::AccountPtr AccountsModelItem::account() const
{
return mPriv->mAccount;
}
void AccountsModelItem::setEnabled(bool value)
{
mPriv->mAccount->setEnabled(value);
}
void AccountsModelItem::setNickname(const QString &value)
{
mPriv->mAccount->setNickname(value);
}
void AccountsModelItem::setAutomaticPresence(int type, const QString &status, const QString &statusMessage)
{
Tp::Presence presence;
presence.setStatus((Tp::ConnectionPresenceType) type, status, statusMessage);
mPriv->mAccount->setAutomaticPresence(presence);
}
void AccountsModelItem::setRequestedPresence(int type, const QString &status, const QString &statusMessage)
{
Tp::Presence presence;
presence.setStatus((Tp::ConnectionPresenceType) type, status, statusMessage);
mPriv->mAccount->setRequestedPresence(presence);
}
void AccountsModelItem::onRemoved()
{
int index = parent()->indexOf(this);
emit childrenRemoved(parent(), index, index);
}
void AccountsModelItem::onChanged()
{
emit changed(this);
}
void AccountsModelItem::onContactsChanged(const Tp::Contacts &addedContacts,
const Tp::Contacts &removedContacts)
{
foreach (const Tp::ContactPtr &contact, removedContacts) {
for (int i = 0; i < size(); ++i) {
ContactModelItem *item = qobject_cast(childAt(i));
if (item->contact() == contact) {
emit childrenRemoved(this, i, i);
break;
}
}
}
// get the list of contact ids in the children
QStringList idList;
int numElems = size();
for (int i = 0; i < numElems; ++i) {
ContactModelItem *item = qobject_cast(childAt(i));
if (item) {
idList.append(item->contact()->id());
}
}
QList newNodes;
foreach (const Tp::ContactPtr &contact, addedContacts) {
if (!idList.contains(contact->id())) {
newNodes.append(new ContactModelItem(contact));
}
}
if (newNodes.count()) {
emit childrenAdded(this, newNodes);
}
}
void AccountsModelItem::onStatusChanged(Tp::ConnectionStatus status)
{
onChanged();
emit connectionStatusChanged(mPriv->mAccount->uniqueIdentifier(), status);
}
void AccountsModelItem::onConnectionChanged(const Tp::ConnectionPtr &connection)
{
onChanged();
// if the connection is invalid or disconnected, clear the contacts list
if (connection.isNull()
|| !connection->isValid()
|| connection->status() == Tp::ConnectionStatusDisconnected) {
if (size() > 0) {
emit childrenRemoved(this, 0, size() - 1);
}
return;
}
mPriv->mManager = connection->contactManager();
connect(mPriv->mManager.data(),
SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts,
Tp::Channel::GroupMemberChangeDetails)),
SLOT(onContactsChanged(Tp::Contacts,Tp::Contacts)));
connect(mPriv->mManager.data(),
SIGNAL(stateChanged(Tp::ContactListState)),
SLOT(onContactManagerStateChanged(Tp::ContactListState)));
onContactManagerStateChanged(mPriv->mManager->state());
}
void AccountsModelItem::onContactManagerStateChanged(Tp::ContactListState state)
{
onChanged();
if (state == Tp::ContactListStateSuccess) {
clearContacts();
addKnownContacts();
}
}
void AccountsModelItem::clearContacts()
{
if (!mPriv->mAccount->connection().isNull() &&
mPriv->mAccount->connection()->isValid()) {
Tp::ContactManagerPtr manager = mPriv->mAccount->connection()->contactManager();
Tp::Contacts contacts = manager->allKnownContacts();
// remove the items no longer present
for (int i = 0; i < size(); ++i) {
bool exists = false;
ContactModelItem *item = qobject_cast(childAt(i));
if (item) {
Tp::ContactPtr itemContact = item->contact();
if (contacts.contains(itemContact)) {
exists = true;
}
}
if (!exists) {
emit childrenRemoved(this, i, i);
}
}
}
}
void AccountsModelItem::addKnownContacts()
{
// reload the known contacts if it has a connection
QList newNodes;
if (!mPriv->mAccount->connection().isNull() &&
mPriv->mAccount->connection()->isValid()) {
Tp::ContactManagerPtr manager = mPriv->mAccount->connection()->contactManager();
Tp::Contacts contacts = manager->allKnownContacts();
// get the list of contact ids in the children
QStringList idList;
int numElems = size();
for (int i = 0; i < numElems; ++i) {
ContactModelItem *item = qobject_cast(childAt(i));
if (item) {
idList.append(item->contact()->id());
}
}
// only add the contact item if it is new
foreach (const Tp::ContactPtr &contact, contacts) {
if (!idList.contains(contact->id())) {
newNodes.append(new ContactModelItem(contact));
}
}
}
if (newNodes.count() > 0) {
emit childrenAdded(this, newNodes);
}
}
}