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();
}
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);
refresh();
}
@ -334,17 +334,20 @@ void Models::Contact::getMessages(Models::Contact::Messages& container) const
void Models::Contact::toOfflineState()
{
emit childIsAboutToBeRemoved(this, 0, childItems.size());
for (std::deque<Item*>::size_type i = 0; i < childItems.size(); ++i) {
Item* item = childItems[i];
disconnect(item, &Item::childChanged, this, &Contact::refresh);
Item::_removeChild(i);
item->deleteLater();
std::deque<Item*>::size_type size = childItems.size();
if (size > 0) {
emit childIsAboutToBeRemoved(this, 0, size - 1);
for (std::deque<Item*>::size_type i = 0; i < size; ++i) {
Item* item = childItems[0];
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

View File

@ -57,7 +57,6 @@ public:
void addPresence(const QString& name, const QMap<QString, QVariant>& data);
void removePresence(const QString& name);
void appendChild(Models::Item * child) override;
QString getContactName() const;
QString getStatus() const;
@ -72,6 +71,7 @@ public:
protected:
void _removeChild(int index) override;
void _appendChild(Models::Item * child) override;
bool columnInvolvedInDisplay(int col) 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);
changed(1);
refresh();
@ -83,9 +83,14 @@ void Models::Group::refresh()
{
unsigned int newAmount(0);
for (std::deque<Models::Item*>::const_iterator itr = childItems.begin(), end = childItems.end(); itr != end; ++itr) {
Models::Contact* cnt = static_cast<Models::Contact*>(*itr);
newAmount += cnt->getMessagesCount();
for (Models::Item* item : childItems) {
if (item->type == reference) {
item = static_cast<Reference*>(item)->dereference();
}
if (item->type == contact) {
Models::Contact* cnt = static_cast<Models::Contact*>(item);
newAmount += cnt->getMessagesCount();
}
}
setUnreadMessages(newAmount);
@ -95,10 +100,15 @@ unsigned int Models::Group::getOnlineContacts() const
{
unsigned int amount(0);
for (std::deque<Models::Item*>::const_iterator itr = childItems.begin(), end = childItems.end(); itr != end; ++itr) {
Models::Contact* cnt = static_cast<Models::Contact*>(*itr);
if (cnt->getAvailability() != Shared::Availability::offline) {
++amount;
for (Models::Item* item : childItems) {
if (item->type == reference) {
item = static_cast<Reference*>(item)->dereference();
}
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();
void appendChild(Models::Item* child) override;
int columnCount() const override;
QVariant data(int column) const override;
@ -41,6 +40,7 @@ public:
protected:
void _removeChild(int index) override;
void _appendChild(Models::Item* child) override;
void setUnreadMessages(unsigned int amount);
private slots:

View File

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

View File

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

View File

@ -29,7 +29,7 @@ Models::Reference::Reference(Models::Item* original, Models::Item* parent):
cx(-1),
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::childInserted, this, &Reference::onChildInserted);
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);
original->addReference(this);
for (int i = 0; i < original->childCount(); i++) {
Reference* ref = new Reference(original->child(i));
Item::appendChild(ref);
}
}
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::childInserted, this, &Reference::onChildInserted);
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)
{
if (parent == original) {
emit childIsAboutToBeRemoved(this, first, last);
for (int i = first; i <= last; ++i) {
Reference* ref = static_cast<Reference*>(childItems[i]);
Item* orig = original->child(i);
orig->removeReference(ref);
Item::removeChild(i);
Reference* ref = static_cast<Reference*>(childItems[first]);
Item::_removeChild(first);
delete ref;
}
childRemoved();
}
}

View File

@ -518,7 +518,6 @@ void Models::Roster::removeGroup(const QString& account, const QString& name)
if (cont->referencesCount() == 1) {
toInsert.push_back(ref);
} else {
cont->removeReference(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;
acc->appendChild(ref);
} else {
cont->removeReference(ref);
delete ref;
}