referencing seems to be working now

This commit is contained in:
Blue 2020-04-18 15:02:01 +03:00
parent 83a2e6af85
commit 9c855553c5
8 changed files with 77 additions and 41 deletions

View File

@ -226,9 +226,9 @@ void Models::Contact::_removeChild(int index)
refresh(); refresh();
} }
void Models::Contact::appendChild(Models::Item* child) void Models::Contact::_appendChild(Models::Item* child)
{ {
Item::appendChild(child); Item::_appendChild(child);
connect(child, &Item::childChanged, this, &Contact::refresh); connect(child, &Item::childChanged, this, &Contact::refresh);
refresh(); refresh();
} }
@ -334,17 +334,20 @@ void Models::Contact::getMessages(Models::Contact::Messages& container) const
void Models::Contact::toOfflineState() void Models::Contact::toOfflineState()
{ {
emit childIsAboutToBeRemoved(this, 0, childItems.size()); std::deque<Item*>::size_type size = childItems.size();
for (std::deque<Item*>::size_type i = 0; i < childItems.size(); ++i) { if (size > 0) {
Item* item = childItems[i]; emit childIsAboutToBeRemoved(this, 0, size - 1);
disconnect(item, &Item::childChanged, this, &Contact::refresh); for (std::deque<Item*>::size_type i = 0; i < size; ++i) {
Item::_removeChild(i); Item* item = childItems[0];
item->deleteLater(); disconnect(item, &Item::childChanged, this, &Contact::refresh);
Item::_removeChild(0);
item->deleteLater();
}
childItems.clear();
presences.clear();
emit childRemoved();
refresh();
} }
childItems.clear();
presences.clear();
emit childRemoved();
refresh();
} }
QString Models::Contact::getDisplayedName() const QString Models::Contact::getDisplayedName() const

View File

@ -57,7 +57,6 @@ public:
void addPresence(const QString& name, const QMap<QString, QVariant>& data); void addPresence(const QString& name, const QMap<QString, QVariant>& data);
void removePresence(const QString& name); void removePresence(const QString& name);
void appendChild(Models::Item * child) override;
QString getContactName() const; QString getContactName() const;
QString getStatus() const; QString getStatus() const;
@ -72,6 +71,7 @@ public:
protected: protected:
void _removeChild(int index) override; void _removeChild(int index) override;
void _appendChild(Models::Item * child) override;
bool columnInvolvedInDisplay(int col) override; bool columnInvolvedInDisplay(int col) override;
const Account* getParentAccount() const override; const Account* getParentAccount() const override;

View File

@ -30,9 +30,9 @@ Models::Group::~Group()
{ {
} }
void Models::Group::appendChild(Models::Item* child) void Models::Group::_appendChild(Models::Item* child)
{ {
Item::appendChild(child); Item::_appendChild(child);
connect(child, &Item::childChanged, this, &Group::refresh); connect(child, &Item::childChanged, this, &Group::refresh);
changed(1); changed(1);
refresh(); refresh();
@ -83,9 +83,14 @@ void Models::Group::refresh()
{ {
unsigned int newAmount(0); unsigned int newAmount(0);
for (std::deque<Models::Item*>::const_iterator itr = childItems.begin(), end = childItems.end(); itr != end; ++itr) { for (Models::Item* item : childItems) {
Models::Contact* cnt = static_cast<Models::Contact*>(*itr); if (item->type == reference) {
newAmount += cnt->getMessagesCount(); item = static_cast<Reference*>(item)->dereference();
}
if (item->type == contact) {
Models::Contact* cnt = static_cast<Models::Contact*>(item);
newAmount += cnt->getMessagesCount();
}
} }
setUnreadMessages(newAmount); setUnreadMessages(newAmount);
@ -95,10 +100,15 @@ unsigned int Models::Group::getOnlineContacts() const
{ {
unsigned int amount(0); unsigned int amount(0);
for (std::deque<Models::Item*>::const_iterator itr = childItems.begin(), end = childItems.end(); itr != end; ++itr) { for (Models::Item* item : childItems) {
Models::Contact* cnt = static_cast<Models::Contact*>(*itr); if (item->type == reference) {
if (cnt->getAvailability() != Shared::Availability::offline) { item = static_cast<Reference*>(item)->dereference();
++amount; }
if (item->type == contact) {
Models::Contact* cnt = static_cast<Models::Contact*>(item);
if (cnt->getAvailability() != Shared::Availability::offline) {
++amount;
}
} }
} }

View File

@ -32,7 +32,6 @@ public:
Group(const QMap<QString, QVariant> &data, Item *parentItem = 0); Group(const QMap<QString, QVariant> &data, Item *parentItem = 0);
~Group(); ~Group();
void appendChild(Models::Item* child) override;
int columnCount() const override; int columnCount() const override;
QVariant data(int column) const override; QVariant data(int column) const override;
@ -41,6 +40,7 @@ public:
protected: protected:
void _removeChild(int index) override; void _removeChild(int index) override;
void _appendChild(Models::Item* child) override;
void setUnreadMessages(unsigned int amount); void setUnreadMessages(unsigned int amount);
private slots: private slots:

View File

@ -29,7 +29,9 @@ Models::Item::Item(Type p_type, const QMap<QString, QVariant> &p_data, Item *p_p
name(""), name(""),
childItems(), childItems(),
parent(p_parent), parent(p_parent),
references() references(),
destroyingByParent(false),
destroyingByOriginal(false)
{ {
QMap<QString, QVariant>::const_iterator itr = p_data.find("name"); QMap<QString, QVariant>::const_iterator itr = p_data.find("name");
if (itr != p_data.end()) { if (itr != p_data.end()) {
@ -48,15 +50,24 @@ Models::Item::Item(const Models::Item& other):
Models::Item::~Item() Models::Item::~Item()
{ {
for (Reference* ref : references) { if (!destroyingByParent) {
Item* parent = ref->parentItem(); Item* parent = parentItem();
if (parent != nullptr) { if (parent != nullptr) {
parent->removeChild(ref->row()); if (parent->type == reference) {
parent->Item::removeChild(row());
} else {
parent->removeChild(row());
}
} }
}
for (Reference* ref : references) {
ref->destroyingByOriginal = true;
delete ref; delete ref;
} }
for (Item* child : childItems) { for (Item* child : childItems) {
child->destroyingByParent = true;
delete child; delete child;
} }
} }
@ -70,6 +81,11 @@ void Models::Item::setName(const QString& p_name)
} }
void Models::Item::appendChild(Models::Item* child) void Models::Item::appendChild(Models::Item* child)
{
_appendChild(child);
}
void Models::Item::_appendChild(Models::Item* child)
{ {
bool moving = false; bool moving = false;
int newRow = 0; int newRow = 0;

View File

@ -88,27 +88,26 @@ class Item : public QObject{
int getContact(const QString& jid) const; int getContact(const QString& jid) const;
std::set<Reference*>::size_type referencesCount() const; std::set<Reference*>::size_type referencesCount() const;
void addReference(Reference* ref);
void removeReference(Reference* ref);
protected: protected:
virtual void changed(int col); virtual void changed(int col);
virtual void _removeChild(int index); virtual void _removeChild(int index);
virtual void _appendChild(Item *child);
virtual bool columnInvolvedInDisplay(int col); virtual bool columnInvolvedInDisplay(int col);
virtual const Account* getParentAccount() const; virtual const Account* getParentAccount() const;
void addReference(Reference* ref);
void removeReference(Reference* ref);
protected slots: protected slots:
void onChildChanged(Models::Item* item, int row, int col); void onChildChanged(Models::Item* item, int row, int col);
virtual void toOfflineState();
protected: protected:
QString name; QString name;
std::deque<Item*> childItems; std::deque<Item*> childItems;
Item* parent; Item* parent;
std::set<Reference*> references; std::set<Reference*> references;
bool destroyingByParent;
protected slots: bool destroyingByOriginal;
virtual void toOfflineState();
}; };
} }

View File

@ -29,7 +29,7 @@ Models::Reference::Reference(Models::Item* original, Models::Item* parent):
cx(-1), cx(-1),
c(false) c(false)
{ {
connect(original, &Item::childChanged, this, &Reference::onChildChanged); connect(original, &Item::childChanged, this, &Reference::onChildChanged, Qt::QueuedConnection);
connect(original, &Item::childIsAboutToBeInserted, this, &Reference::onChildIsAboutToBeInserted); connect(original, &Item::childIsAboutToBeInserted, this, &Reference::onChildIsAboutToBeInserted);
connect(original, &Item::childInserted, this, &Reference::onChildInserted); connect(original, &Item::childInserted, this, &Reference::onChildInserted);
connect(original, &Item::childIsAboutToBeRemoved, this, &Reference::onChildIsAboutToBeRemoved); connect(original, &Item::childIsAboutToBeRemoved, this, &Reference::onChildIsAboutToBeRemoved);
@ -38,10 +38,20 @@ Models::Reference::Reference(Models::Item* original, Models::Item* parent):
connect(original, &Item::childMoved, this, &Reference::onChildMoved); connect(original, &Item::childMoved, this, &Reference::onChildMoved);
original->addReference(this); original->addReference(this);
for (int i = 0; i < original->childCount(); i++) {
Reference* ref = new Reference(original->child(i));
Item::appendChild(ref);
}
} }
Models::Reference::~Reference() Models::Reference::~Reference()
{ {
if (!destroyingByOriginal) {
original->removeReference(this);
}
disconnect(original, &Item::childChanged, this, &Reference::onChildChanged);
disconnect(original, &Item::childIsAboutToBeInserted, this, &Reference::onChildIsAboutToBeInserted); disconnect(original, &Item::childIsAboutToBeInserted, this, &Reference::onChildIsAboutToBeInserted);
disconnect(original, &Item::childInserted, this, &Reference::onChildInserted); disconnect(original, &Item::childInserted, this, &Reference::onChildInserted);
disconnect(original, &Item::childIsAboutToBeRemoved, this, &Reference::onChildIsAboutToBeRemoved); disconnect(original, &Item::childIsAboutToBeRemoved, this, &Reference::onChildIsAboutToBeRemoved);
@ -120,13 +130,13 @@ void Models::Reference::onChildInserted()
void Models::Reference::onChildIsAboutToBeRemoved(Models::Item* parent, int first, int last) void Models::Reference::onChildIsAboutToBeRemoved(Models::Item* parent, int first, int last)
{ {
if (parent == original) { if (parent == original) {
emit childIsAboutToBeRemoved(this, first, last);
for (int i = first; i <= last; ++i) { for (int i = first; i <= last; ++i) {
Reference* ref = static_cast<Reference*>(childItems[i]); Reference* ref = static_cast<Reference*>(childItems[first]);
Item* orig = original->child(i); Item::_removeChild(first);
orig->removeReference(ref);
Item::removeChild(i);
delete ref; delete ref;
} }
childRemoved();
} }
} }

View File

@ -518,7 +518,6 @@ void Models::Roster::removeGroup(const QString& account, const QString& name)
if (cont->referencesCount() == 1) { if (cont->referencesCount() == 1) {
toInsert.push_back(ref); toInsert.push_back(ref);
} else { } else {
cont->removeReference(ref);
delete ref; delete ref;
} }
} }
@ -626,7 +625,6 @@ void Models::Roster::removeContact(const QString& account, const QString& jid, c
qDebug() << "An attempt to remove last instance of contact" << jid << "from the group" << group << ", contact will be moved to ungrouped contacts of" << account; qDebug() << "An attempt to remove last instance of contact" << jid << "from the group" << group << ", contact will be moved to ungrouped contacts of" << account;
acc->appendChild(ref); acc->appendChild(ref);
} else { } else {
cont->removeReference(ref);
delete ref; delete ref;
} }