Example #1
0
void ContactListModel::Private::removeContact(PsiContact *contact)
{
    Q_ASSERT(monitoredContacts.contains(contact));
    if (!monitoredContacts.contains(contact))
        return;

    while (monitoredContacts.contains(contact)) {
        QModelIndex index = monitoredContacts.take(contact);
        if (!index.isValid()) {
            continue;
        }

        q->beginRemoveRows(index.parent(), index.row(), index.row());
        ContactListItem *item = q->toItem(index);
        ContactListItem *group = item->parent();

        delete item;
        q->endRemoveRows();

        index = q->toModelIndex(group);
        // Delete empty group
        if (group->isGroup() && !group->childCount()) {
            q->beginRemoveRows(index.parent(), index.row(), index.row());
            delete group;
            q->endRemoveRows();

        }
        else {
            // Update group
            emit q->dataChanged(index, index);
        }
    }
    disconnect(contact, nullptr, this, nullptr);
    operationQueue.remove(contact);
}
Example #2
0
void ContactListModel::Private::clear()
{
    q->beginResetModel();

    // disconnect accounts. they have nothing to update here after clear
    for (const auto &child : q->root()->children()) {
        ContactListItem *item = static_cast<ContactListItem*>(child);
        if (item->isAccount()) {
            cleanUpAccount(item->account());
        }
    }

    qDeleteAll(q->root()->children());

    operationQueue.clear();

    QHashIterator<PsiContact*, QPersistentModelIndex> it(monitoredContacts);
    while (it.hasNext()) {
        it.next();
        disconnect(it.key(), nullptr, this, nullptr);
    }
    monitoredContacts.clear();

    q->endResetModel();
}
Example #3
0
PsiContact* ContactListModel::contactFor(const QModelIndex& index) const
{
    ContactListItem *item = static_cast<ContactListItem*>(index.internalPointer());
    if (item->type() != ContactListItem::Type::ContactType)
        return nullptr;

    return item->contact();
}
Example #4
0
QVariant ContactListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    ContactListItem* item = toItem(index);

    if (role == ContactListItemRole)
        return QVariant::fromValue(item);
    else
        return item->value(role);
}
Example #5
0
void ContactListModel::Private::updateAccount()
{
    PsiAccount *account = qobject_cast<PsiAccount*>(sender());
    if (account->enabled()) {
        ContactListItem *root = static_cast<ContactListItem*>(q->root());;
        ContactListItem *accountItem = root->findAccount(account);
        Q_ASSERT(accountItem);
        q->updateItem(accountItem);
    } else {
        cleanUpAccount(account);
    }
}
Example #6
0
void ContactListModel::Private::cleanUpAccount(PsiAccount *account)
{
    disconnect(account, nullptr, this, nullptr);
    ContactListItem *root = static_cast<ContactListItem*>(q->root());
    ContactListItem *item = root->findAccount(account);
    if (!item) {
        qCritical("BUG: account was already removed from the list");
        return;
    }
    QModelIndex index = q->toModelIndex(item);
    q->beginRemoveRows(index.parent(), index.row(), index.row());
    delete item;
    q->endRemoveRows();
}
Example #7
0
/**
 * Returns the item flags for the given \param index in the model.
 */
Qt::ItemFlags ContactListModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::ItemIsDropEnabled;

    Qt::ItemFlags f = QAbstractItemModel::flags(index);
    f |= Qt::ItemIsSelectable | Qt::ItemIsEnabled;

    ContactListItem *item = toItem(index);
    if ((index.column() == NameColumn) && item && item->isEditable())
        f |= Qt::ItemIsEditable;

    if (!item->isExpandable())
        f |= Qt::ItemNeverHasChildren;

    return f;
}
Example #8
0
void ContactListModel::Private::contactUpdated()
{
    PsiContact *contact = qobject_cast<PsiContact*>(sender());
    Q_ASSERT(monitoredContacts.contains(contact));
    if (!monitoredContacts.contains(contact))
        return;

    // Check for groups changing
    // Maybe very difficult and should be simplified?
    QList<ContactListItem*> groupItems;
    for (const QPersistentModelIndex &index: monitoredContacts.values(contact)) {
        ContactListItem *item = q->toItem(index);
        ContactListItem *parent = item->parent();
        if (parent && parent->isGroup()) {
            groupItems << parent;
        }
    }

    Operation operation = Operation::UpdateContact;
    ContactListItem::SpecialGroupType specialGroupType = specialGroupFor(contact);
    if (specialGroupType == ContactListItem::SpecialGroupType::NoneSpecialGroupType) {
        QStringList groups1;
        for (ContactListItem *item: groupItems) {
            groups1 << item->name();
        }
        groups1.sort();
        QStringList groups2 = contact->groups();
        groups2.sort();
        if (groups1 != groups2) {
            operation = Operation::ContactGroupsChanged;
        }
    }
    else if (groupItems.size() > 1 || (!groupItems.isEmpty() && groupItems.first()->specialGroupType() != specialGroupType)) {
        operation = Operation::ContactGroupsChanged;
    }

    addOperation(contact, operation);
}
Example #9
0
void ContactList::addContact(const QString &contactName, const QPixmap &pixmap)
{
    ContactListItem *contact = new ContactListItem(d->mFrame);
    contact->setName(contactName);
    contact->setPixmap(pixmap);
    contact->setPos(0.0, d->mFrame->contentRect().height());
    d->mFrame->setContentRect(QRectF(0.0, boundingRect().y(),
                                     contact->boundingRect().width(),
                                     d->mFrame->contentRect().height() + contact->boundingRect().height()));
    d->mContacts.append(contact);
}
Example #10
0
bool ContactListProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
	QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
	if (!index.isValid())
		return false;

	ContactListItemProxy* itemProxy = static_cast<ContactListItemProxy*>(index.internalPointer());
	ContactListItem* item = itemProxy ? itemProxy->item() : 0;
	if (!item) {
		Q_ASSERT(false);
		return false;
	}

	if (item->editing()) {
		return true;
	}

	switch (ContactListModel::indexType(index)) {
	case ContactListModel::ContactType: {
		PsiContact* psiContact = dynamic_cast<PsiContact*>(item);

		if (psiContact->isHidden()) {
			return false;
		}

		if (psiContact->isSelf()) {
			return showSelf();
		}
		else if (psiContact->isAgent()) {
			return showTransports();
		}

		if (!showOffline()) {
			return psiContact->isOnline();
		}
		else {
			return true;
		}
	}
	case ContactListModel::GroupType:
		{
			ContactListGroup::SpecialType specialGroupType = static_cast<ContactListGroup::SpecialType>(index.data(ContactListModel::SpecialGroupTypeRole).toInt());
			if (specialGroupType != ContactListGroup::SpecialType_None) {
				if (specialGroupType == ContactListGroup::SpecialType_Transports)
					return showTransports();
			}

			if (!showOffline()) {
				ContactListGroup* group = dynamic_cast<ContactListGroup*>(item);
				return group->haveOnlineContacts();
			}
			else {
				return true;
			}
		}
	case ContactListModel::AccountType:
		return true;
	case ContactListModel::InvalidType:
		return true;
	default:
		Q_ASSERT(false);
	}

	return true;
}
Example #11
0
void ContactListModel::Private::realAddContact(PsiContact *contact)
{
    ContactListItem *root = static_cast<ContactListItem*>(q->root());;
    if (accountsEnabled) {
        PsiAccount *account = contact->account();
        ContactListItem *accountItem = root->findAccount(account);

        if (!accountItem) {
            accountItem = new ContactListItem(q, ContactListItem::Type::AccountType);
            accountItem->setAccount(account);
            accountItem->setExpanded(!collapsed.contains(accountItem->internalName()));

            connect(account, SIGNAL(accountDestroyed()), SLOT(onAccountDestroyed()));
            connect(account, SIGNAL(updatedAccount()), SLOT(updateAccount()));

            root->appendChild(accountItem);
        }
        root = accountItem;
    }

    if (!contact->isSelf() && groupsEnabled) {
        ContactListItem::SpecialGroupType specialGroupType = specialGroupFor(contact);
        QStringList groups = specialGroupType == ContactListItem::SpecialGroupType::NoneSpecialGroupType ? contact->groups() : QStringList{QString()};

        for (const QString &groupName: groups) {

            ContactListItem *groupItem = nullptr;
            if (specialGroupType == ContactListItem::SpecialGroupType::NoneSpecialGroupType)
                groupItem = root->findGroup(groupName);
            else
                groupItem = root->findGroup(specialGroupType);

            // No duplicates
            if (groupItem && groupItem->findContact(contact)) {
                continue;
            }

            ContactListItem *item = new ContactListItem(q, ContactListItem::Type::ContactType);
            item->setContact(contact);

            if (!groupItem) {
                groupItem = new ContactListItem(q, ContactListItem::Type::GroupType, specialGroupType);
                if (specialGroupType == ContactListItem::SpecialGroupType::NoneSpecialGroupType)
                    groupItem->setName(groupName);

                root->appendChild(groupItem);
                groupItem->setExpanded(!collapsed.contains(groupItem->internalName()));
                groupItem->setHidden(hidden.contains(groupItem->internalName()));
            }
            groupItem->appendChild(item);

            monitoredContacts.insertMulti(contact, q->toModelIndex(item));
        }
    }
    else {
        ContactListItem *item = new ContactListItem(q, ContactListItem::Type::ContactType);
        item->setContact(contact);
        root->appendChild(item);
        monitoredContacts.insertMulti(contact, q->toModelIndex(item));
    }

    connect(contact, SIGNAL(destroyed(PsiContact*)), SLOT(removeContact(PsiContact*)));
    connect(contact, SIGNAL(groupsChanged()), SLOT(contactGroupsChanged()));
    connect(contact, SIGNAL(updated()), SLOT(contactUpdated()));
    connect(contact, SIGNAL(alert()), SLOT(contactUpdated()));
    connect(contact, SIGNAL(anim()), SLOT(contactUpdated()));
}
Example #12
0
bool ContactListModel::setData(const QModelIndex &index, const QVariant &data, int role)
{
    if (!index.isValid())
        return false;

    ContactListItem *item = toItem(index);
    if (!item)
        return false;
    PsiContact *contact = item->isContact() ? item->contact() : nullptr;

    if (role == ActivateRole) {
        if (!contact)
            return false;

        contact->activate();
        return true;
    }
    else if (role == Qt::EditRole) {
        QString name = data.toString();
        if (contact) {
            item->setName(name);
            emit dataChanged(index, index);
        }
        else if (item->isGroup() && !name.isEmpty()) {
            QString oldName = item->name();
            QList<PsiContact*> contacts;
            for (int i = 0; i < item->childCount(); ++i) {
                if (item->child(i)->isContact())
                contacts << item->child(i)->contact();
            }

            for (PsiContact *contact: contacts) {
                QStringList groups = contact->groups();
                groups.removeOne(oldName);
                groups << name;
                contact->setGroups(groups);
            }

        }

        return true;
    }
    else if (role == ExpandedRole) {
        if (!item->isContact()) {
            item->setExpanded(data.toBool());
        }
    }

    return true;
}