haiku/src/apps/mail/People.cpp

196 lines
3.2 KiB
C++

/*
* Copyright 2015-2016, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include "People.h"
#include <stdio.h>
#include <Autolock.h>
#include <Node.h>
static BString
PersonName(BNode& node)
{
BString fullName;
node.ReadAttrString("META:name", &fullName);
return fullName;
}
static void
AddPersonAddresses(BNode& node, BStringList& addresses)
{
BString email;
if (node.ReadAttrString("META:email", &email) != B_OK || email.IsEmpty())
return;
addresses.Add(email);
// Support for 3rd-party People apps
for (int i = 2; i < 99; i++) {
char attr[32];
snprintf(attr, sizeof(attr), "META:email%d", i);
if (node.ReadAttrString(attr, &email) != B_OK)
break;
addresses.Add(email);
}
}
static void
AddPersonGroups(BNode& node, BStringList& groups)
{
BString groupString;
if (node.ReadAttrString("META:group", &groupString) != B_OK
|| groupString.IsEmpty()) {
return;
}
int first = 0;
while (first < groupString.Length()) {
int end = groupString.FindFirst(',', first);
if (end < 0)
end = groupString.Length();
BString group;
groupString.CopyInto(group, first, end - first);
group.Trim();
groups.Add(group);
first = end + 1;
}
}
// #pragma mark - Person
Person::Person(const entry_ref& ref)
{
BNode node(&ref);
if (node.InitCheck() != B_OK)
return;
fName = PersonName(node);
AddPersonAddresses(node, fAddresses);
AddPersonGroups(node, fGroups);
}
Person::~Person()
{
}
bool
Person::IsInGroup(const char* group) const
{
for (int32 index = 0; index < CountGroups(); index++) {
if (GroupAt(index) == group)
return true;
}
return false;
}
// #pragma mark - PersonList
PersonList::PersonList(QueryList& query)
:
fQueryList(query),
fPersons(10, true)
{
fQueryList.AddListener(this);
}
PersonList::~PersonList()
{
fQueryList.RemoveListener(this);
}
void
PersonList::EntryCreated(QueryList& source, const entry_ref& ref, ino_t node)
{
BAutolock locker(this);
Person* person = new Person(ref);
fPersons.AddItem(person);
fPersonMap.insert(std::make_pair(node_ref(ref.device, node), person));
}
void
PersonList::EntryRemoved(QueryList& source, const node_ref& nodeRef)
{
BAutolock locker(this);
PersonMap::iterator found = fPersonMap.find(nodeRef);
if (found != fPersonMap.end()) {
Person* person = found->second;
fPersonMap.erase(found);
fPersons.RemoveItem(person);
}
}
// #pragma mark - GroupList
GroupList::GroupList(QueryList& query)
:
fQueryList(query)
{
fQueryList.AddListener(this);
}
GroupList::~GroupList()
{
fQueryList.RemoveListener(this);
}
void
GroupList::EntryCreated(QueryList& source, const entry_ref& ref, ino_t _node)
{
BNode node(&ref);
if (node.InitCheck() != B_OK)
return;
BAutolock locker(this);
BStringList groups;
AddPersonGroups(node, groups);
for (int32 index = 0; index < groups.CountStrings(); index++) {
BString group = groups.StringAt(index);
StringCountMap::iterator found = fGroupMap.find(group);
if (found != fGroupMap.end())
found->second++;
else {
fGroupMap[group] = 1;
fGroups.Add(group);
}
}
// TODO: sort groups
}
void
GroupList::EntryRemoved(QueryList& source, const node_ref& nodeRef)
{
// TODO!
}