Mail: Avoid duplicate Person items

Duplicates can arise if e.g. you have backup of your contacts mounted.
Or, imagine someone packages a Person file with their software as it
was common back in the BeOS days. If you have several software packages
from that dev, you'll see copies of that Person file from each package.

If a contact has the same name, we compare all email addresses. If they
differ, a new item is created. That way, Person files with more than
one email attribute ("META:email{n}" with n >= 2), as used by other apps
like Peeps!, get an item per address.

When checking for email addresses in AddPersonAddresses(), don't quit
looking through the attributes when encountering an empty one via "break".
Do "continue" with the next "META:email{n}" attribute, as it's possible
META:email2 is empty, but META:email3 has an address.

Change-Id: I644cfa2d8349b5022ffde37344c55a54577b12f8
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9331
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Humdinger
2025-06-09 16:25:12 +00:00
committed by waddlesplash
parent 1ebc7b923c
commit ba28b6f5f7
+24 -1
View File
@@ -37,7 +37,7 @@ AddPersonAddresses(BNode& node, BStringList& addresses)
snprintf(attr, sizeof(attr), "META:email%d", i);
if (node.ReadAttrString(attr, &email) != B_OK || email.IsEmpty())
break;
continue;
addresses.Add(email);
}
@@ -124,6 +124,29 @@ PersonList::EntryCreated(QueryList& source, const entry_ref& ref, ino_t node)
BAutolock locker(this);
Person* person = new Person(ref);
const BString& name = person->Name();
bool isUnique = true;
for (int32 index = 0; index < fPersons.CountItems(); index++) {
const Person* item = (Person*)fPersons.ItemAt(index);
const BString& itemName = item->Name();
if (itemName != name)
continue;
isUnique = false;
for (int32 addressIndex = 0; addressIndex < person->CountAddresses(); addressIndex++) {
const BString& address = person->AddressAt(addressIndex);
const BString& itemAddress = item->AddressAt(addressIndex);
if (itemAddress != address) {
isUnique = true;
break;
}
}
}
if (!isUnique)
return;
fPersons.AddItem(person);
fPersonMap.insert(std::make_pair(node_ref(ref.device, node), person));
}