Skip to content
Snippets Groups Projects
Commit f26e5e93 authored by Emmanuel Lepage Vallee's avatar Emmanuel Lepage Vallee
Browse files

[ #36988 ] Fix a race condition when changing the number of PhoneNumbers

parent 88839b9b
No related branches found
No related tags found
No related merge requests found
...@@ -124,11 +124,16 @@ const QString& Contact::department() const ...@@ -124,11 +124,16 @@ const QString& Contact::department() const
///Set the phone number (type and number) ///Set the phone number (type and number)
void Contact::setPhoneNumbers(PhoneNumbers numbers) void Contact::setPhoneNumbers(PhoneNumbers numbers)
{ {
const int oldCount(m_Numbers.size()),newCount(numbers.size());
foreach(PhoneNumber* n, m_Numbers) foreach(PhoneNumber* n, m_Numbers)
disconnect(n,SIGNAL(presentChanged(bool)),this,SLOT(slotPresenceChanged())); disconnect(n,SIGNAL(presentChanged(bool)),this,SLOT(slotPresenceChanged()));
m_Numbers = numbers; m_Numbers = numbers;
if (newCount < oldCount) //Rows need to be removed from models first
emit phoneNumberCountAboutToChange(newCount,oldCount);
foreach(PhoneNumber* n, m_Numbers) foreach(PhoneNumber* n, m_Numbers)
connect(n,SIGNAL(presentChanged(bool)),this,SLOT(slotPresenceChanged())); connect(n,SIGNAL(presentChanged(bool)),this,SLOT(slotPresenceChanged()));
if (newCount > oldCount) //Need to be updated after the data to prevent invalid memory access
emit phoneNumberCountChanged(newCount,oldCount);
emit changed(); emit changed();
} }
......
...@@ -133,6 +133,8 @@ Q_SIGNALS: ...@@ -133,6 +133,8 @@ Q_SIGNALS:
void presenceChanged( PhoneNumber* ); void presenceChanged( PhoneNumber* );
void statusChanged ( bool ); void statusChanged ( bool );
void changed ( ); void changed ( );
void phoneNumberCountChanged(int,int);
void phoneNumberCountAboutToChange(int,int);
protected: protected:
//Presence secret methods //Presence secret methods
......
...@@ -94,6 +94,8 @@ ContactTreeBinder::ContactTreeBinder(ContactProxyModel* m,ContactTreeNode* n) : ...@@ -94,6 +94,8 @@ ContactTreeBinder::ContactTreeBinder(ContactProxyModel* m,ContactTreeNode* n) :
QObject(),m_pTreeNode(n),m_pModel(m) QObject(),m_pTreeNode(n),m_pModel(m)
{ {
connect(n->m_pContact,SIGNAL(changed()),this,SLOT(slotContactChanged())); connect(n->m_pContact,SIGNAL(changed()),this,SLOT(slotContactChanged()));
connect(n->m_pContact,SIGNAL(phoneNumberCountChanged(int,int)),this,SLOT(slotPhoneNumberCountChanged(int,int)));
connect(n->m_pContact,SIGNAL(phoneNumberCountAboutToChange(int,int)),this,SLOT(slotPhoneNumberCountAboutToChange(int,int)));
} }
...@@ -101,7 +103,9 @@ void ContactTreeBinder::slotContactChanged() ...@@ -101,7 +103,9 @@ void ContactTreeBinder::slotContactChanged()
{ {
const QModelIndex idx = m_pModel->index(m_pTreeNode->m_Index,0,m_pModel->index(m_pTreeNode->m_pParent3->m_Index,0)); const QModelIndex idx = m_pModel->index(m_pTreeNode->m_Index,0,m_pModel->index(m_pTreeNode->m_pParent3->m_Index,0));
const QModelIndex lastPhoneIdx = m_pModel->index(m_pTreeNode->m_pContact->phoneNumbers().size()-1,0,idx); const QModelIndex lastPhoneIdx = m_pModel->index(m_pTreeNode->m_pContact->phoneNumbers().size()-1,0,idx);
emit m_pModel->dataChanged(idx,lastPhoneIdx); emit m_pModel->dataChanged(idx,idx);
if (lastPhoneIdx.isValid()) //Need to be done twice
emit m_pModel->dataChanged(m_pModel->index(0,0,idx),lastPhoneIdx);
} }
void ContactTreeBinder::slotStatusChanged() void ContactTreeBinder::slotStatusChanged()
...@@ -109,6 +113,27 @@ void ContactTreeBinder::slotStatusChanged() ...@@ -109,6 +113,27 @@ void ContactTreeBinder::slotStatusChanged()
} }
void ContactTreeBinder::slotPhoneNumberCountChanged(int count, int oldCount)
{
const QModelIndex idx = m_pModel->index(m_pTreeNode->m_Index,0,m_pModel->index(m_pTreeNode->m_pParent3->m_Index,0));
if (count > oldCount) {
const QModelIndex lastPhoneIdx = m_pModel->index(oldCount-1,0,idx);
m_pModel->beginInsertRows(idx,oldCount,count-1);
m_pModel->endInsertRows();
}
emit m_pModel->dataChanged(idx,idx);
}
void ContactTreeBinder::slotPhoneNumberCountAboutToChange(int count, int oldCount)
{
const QModelIndex idx = m_pModel->index(m_pTreeNode->m_Index,0,m_pModel->index(m_pTreeNode->m_pParent3->m_Index,0));
if (count < oldCount) {
//If count == 1, disable all children
m_pModel->beginRemoveRows(idx,count == 1?0:count,oldCount-1);
m_pModel->endRemoveRows();
}
}
// //
ContactProxyModel::ContactProxyModel(AbstractContactBackend* parent,int role, bool showAll) : QAbstractItemModel(QCoreApplication::instance()), ContactProxyModel::ContactProxyModel(AbstractContactBackend* parent,int role, bool showAll) : QAbstractItemModel(QCoreApplication::instance()),
m_pModel(parent),m_Role(role),m_ShowAll(showAll),m_lCategoryCounter() m_pModel(parent),m_Role(role),m_ShowAll(showAll),m_lCategoryCounter()
......
...@@ -85,7 +85,7 @@ private Q_SLOTS: ...@@ -85,7 +85,7 @@ private Q_SLOTS:
void slotContactAdded(Contact* c); void slotContactAdded(Contact* c);
}; };
class ContactTreeBinder : public QObject { class ContactTreeBinder : public QObject { //FIXME Qt5 remove when dropping Qt4
Q_OBJECT Q_OBJECT
public: public:
ContactTreeBinder(ContactProxyModel* m,ContactTreeNode* n); ContactTreeBinder(ContactProxyModel* m,ContactTreeNode* n);
...@@ -95,6 +95,8 @@ private: ...@@ -95,6 +95,8 @@ private:
private Q_SLOTS: private Q_SLOTS:
void slotContactChanged(); void slotContactChanged();
void slotStatusChanged(); void slotStatusChanged();
void slotPhoneNumberCountChanged(int,int);
void slotPhoneNumberCountAboutToChange(int,int);
}; };
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment