vscode-theme-onelight/samples/c++.cpp
2021-05-15 17:24:07 +08:00

162 lines
3.8 KiB
C++

#include "ContactsModel.h"
#include "core/IdentityManager.h"
#include "core/ContactsManager.h"
#include <QDebug>
inline bool contactSort(const ContactUser *c1, const ContactUser *c2)
{
if (c1->status() != c2->status())
return c1->status() < c2->status();
return c1->nickname().localeAwareCompare(c2->nickname()) < 0;
}
ContactsModel::ContactsModel(QObject *parent)
: QAbstractListModel(parent), m_identity(0)
{
}
void ContactsModel::setIdentity(UserIdentity *identity)
{
if (identity == m_identity)
return;
beginResetModel();
foreach (ContactUser *user, contacts)
user->disconnect(this);
contacts.clear();
if (m_identity) {
disconnect(m_identity, 0, this, 0);
disconnect(&m_identity->contacts, 0, this, 0);
}
m_identity = identity;
if (m_identity) {
connect(&identity->contacts, SIGNAL(contactAdded(ContactUser*)), SLOT(contactAdded(ContactUser*)));
contacts = identity->contacts.contacts();
std::sort(contacts.begin(), contacts.end(), contactSort);
foreach (ContactUser *user, contacts)
connectSignals(user);
}
endResetModel();
emit identityChanged();
}
QModelIndex ContactsModel::indexOfContact(ContactUser *user) const
{
int row = contacts.indexOf(user);
if (row < 0)
return QModelIndex();
return index(row, 0);
}
ContactUser *ContactsModel::contact(int row) const
{
return contacts.value(row);
}
void ContactsModel::updateUser(ContactUser *user)
{
if (!user)
{
user = qobject_cast<ContactUser*>(sender());
if (!user)
return;
}
int row = contacts.indexOf(user);
if (row < 0)
{
user->disconnect(this);
return;
}
QList<ContactUser*> sorted = contacts;
std::sort(sorted.begin(), sorted.end(), contactSort);
int newRow = sorted.indexOf(user);
if (row != newRow)
{
beginMoveRows(QModelIndex(), row, row, QModelIndex(), (newRow > row) ? (newRow+1) : newRow);
contacts = sorted;
endMoveRows();
}
emit dataChanged(index(newRow, 0), index(newRow, 0));
}
void ContactsModel::connectSignals(ContactUser *user)
{
connect(user, SIGNAL(statusChanged()), SLOT(updateUser()));
connect(user, SIGNAL(nicknameChanged()), SLOT(updateUser()));
connect(user, SIGNAL(contactDeleted(ContactUser*)), SLOT(contactRemoved(ContactUser*)));
}
void ContactsModel::contactAdded(ContactUser *user)
{
Q_ASSERT(!indexOfContact(user).isValid());
connectSignals(user);
QList<ContactUser*>::Iterator lp = qLowerBound(contacts.begin(), contacts.end(), user, contactSort);
int row = lp - contacts.begin();
beginInsertRows(QModelIndex(), row, row);
contacts.insert(lp, user);
endInsertRows();
}
void ContactsModel::contactRemoved(ContactUser *user)
{
if (!user && !(user = qobject_cast<ContactUser*>(sender())))
return;
int row = contacts.indexOf(user);
beginRemoveRows(QModelIndex(), row, row);
contacts.removeAt(row);
endRemoveRows();
disconnect(user, 0, this, 0);
}
QHash<int,QByteArray> ContactsModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "name";
roles[PointerRole] = "contact";
roles[StatusRole] = "status";
return roles;
}
int ContactsModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return contacts.size();
}
QVariant ContactsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= contacts.size())
return QVariant();
ContactUser *user = contacts[index.row()];
switch (role)
{
case Qt::DisplayRole:
case Qt::EditRole:
return user->nickname();
case PointerRole:
return QVariant::fromValue(user);
case StatusRole:
return user->status();
}
return QVariant();
}