<commit_before>/* KPilot
**
** Copyright (C) 1998-2001 by <NAME>
** Copyright (C) 2003-2004 <NAME> <<EMAIL>>
**
** This is a C++ wrapper for the pilot's address database structures.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to <EMAIL>
*/


static const char *pilotadress_id =
	"$Id$";

#ifndef _KPILOT_OPTIONS_H
#include "options.h"
#endif

#include <stdlib.h>
#include <assert.h>

#include <qtextcodec.h>
#include <qstringlist.h>

#include "pilotAddress.h"


#define MAXFIELDS 19

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo,
	PilotRecord * rec) :
	PilotAppCategory(rec),
	fAppInfo(appInfo),
	fAddressInfo()
{
	FUNCTIONSETUPL(4);
	if (rec) unpack_Address(&fAddressInfo, (unsigned char *) rec->getData(), rec->getLen());
	(void) pilotadress_id;
	_loadMaps();
}

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo) :
	PilotAppCategory(),
	fAppInfo(appInfo)
{
	FUNCTIONSETUPL(4);
	reset();

	// assign the phoneLabel so it doesn't appear in the pilot as
	// work for all fields, but at least shows other fields
	fAddressInfo.phoneLabel[0] = (int) eWork;
	fAddressInfo.phoneLabel[1] = (int) eHome;
	fAddressInfo.phoneLabel[2] = (int) eOther;
	fAddressInfo.phoneLabel[3] = (int) eMobile;
	fAddressInfo.phoneLabel[4] = (int) eEmail;

	_loadMaps();
}

PilotAddress::PilotAddress(const PilotAddress & copyFrom) :
	PilotAppCategory(copyFrom),
	fAppInfo(copyFrom.fAppInfo),
	fAddressInfo()
{
	FUNCTIONSETUPL(4);
	_copyAddressInfo(copyFrom.fAddressInfo);

	_loadMaps();
}

PilotAddress & PilotAddress::operator = (const PilotAddress & copyFrom)
{
	FUNCTIONSETUPL(4);
	PilotAppCategory::operator = (copyFrom);
	_copyAddressInfo(copyFrom.fAddressInfo);
	return *this;
}

bool PilotAddress::operator==(const PilotAddress &compareTo)
{
	FUNCTIONSETUPL(4);
	// TODO: call == of PilotAppCategory. I don't think this is necessary, but I'm not so sure...
//	if (!(PilotAppCategory)(this)->operator==(compareTo) ) return false;

	// now compare all the fields stored in the fAddressInfo.entry array of char*[19]
	for (int i=0; i<MAXFIELDS; i++) {
		// if one is NULL, and the other non-empty, they are not equal for sure
		if ( !getFieldP(i) && compareTo.getFieldP(i)) return false;
		if ( getFieldP(i) && !compareTo.getFieldP(i)) return false;
		// test for getField(i)!=... to prevent strcmp or NULL strings!  None or both can be zero, but not a single one.
		if ( (getFieldP(i) != compareTo.getFieldP(i)) && ( strcmp(getFieldP(i), compareTo.getFieldP(i)) ) )  return false;
	}
	return true;
}


void PilotAddress::_copyAddressInfo(const struct Address &copyFrom)
{
	FUNCTIONSETUPL(4);
	fAddressInfo.showPhone = copyFrom.showPhone;

	for (int labelLp = 0; labelLp < 5; labelLp++)
	{
		fAddressInfo.phoneLabel[labelLp] =
			copyFrom.phoneLabel[labelLp];
	}

	for (int entryLp = 0; entryLp < MAXFIELDS; entryLp++)
	{
		if (copyFrom.entry[entryLp])
			fAddressInfo.entry[entryLp] =
				qstrdup(copyFrom.entry[entryLp]);
		else
			fAddressInfo.entry[entryLp] = 0L;
	}
}


PilotAddress::~PilotAddress()
{
	FUNCTIONSETUPL(4);
	free_Address(&fAddressInfo);
}

QString PilotAddress::getTextRepresentation(bool richText)
{
	QString text, tmp;

	QString par = richText?CSL1("<p>"):CSL1("");
	QString ps = richText?CSL1("</p>"):CSL1("\n");
	QString br = richText?CSL1("<br/>"):CSL1("\n");

	// title + name
	text += par;
	if (!getField(entryTitle).isEmpty())
	{
		text += rtExpand(getField(entryTitle), richText);
		text += CSL1(" ");
	}

	tmp = richText?CSL1("<b><big>%1%2%3</big></b>"):CSL1("%1%2%3");
	if (!getField(entryFirstname).isEmpty())
		tmp=rtExpand(tmp.arg(getField(entryFirstname)), richText).arg(CSL1(" "));
	else
		tmp=tmp.arg(CSL1(" ")).arg(CSL1(" "));
	tmp=tmp.arg(rtExpand(getField(entryLastname), richText));
	text += tmp;
	text += ps;

	// company
	if (!getField(entryCompany).isEmpty())
	{
		text += par;
		text += rtExpand(getField(entryCompany), richText);
		text += ps;
	}

	// phone numbers (+ labels)
	text += par;
	for (int i = entryPhone1; i <= entryPhone5; i++)
		if (!getField(i).isEmpty())
		{
			if (richText)
			{
				if (getShownPhone() == i - entryPhone1)
					tmp=CSL1("<small>%1: </small><b>%2</b>");
				else
					tmp=CSL1("<small>%1: </small>%2");
			}
			else
				tmp=CSL1("%1: %2");
			tmp=tmp.arg(PilotAppCategory::codec()->toUnicode(
				fAppInfo.phoneLabels[getPhoneLabelIndex(i-entryPhone1)]));
			tmp=tmp.arg(rtExpand(getField(i), richText));
			text += tmp;
			text += br;
		}
	text += ps;

	// address, city, state, country
	text += par;
	if (!getField(entryAddress).isEmpty())
	{
		text += rtExpand(getField(entryAddress), richText);
		text += br;
	}
	if (!getField(entryCity).isEmpty())
	{
		text += rtExpand(getField(entryCity), richText);
		text += CSL1(" ");
	}
	if (!getField(entryState).isEmpty())
	{
		text += rtExpand(getField(entryState), richText);
		text += CSL1(" ");
	}
	if (!getField(entryZip).isEmpty())
	{
		text += rtExpand(getField(entryZip), richText);
	}
	text += br;
	if (!getField(entryCountry).isEmpty())
	{
		text += rtExpand(getField(entryCountry), richText);
		text += br;
	}
	text += ps;

	// custom fields
	text += par;
	for (int i = entryCustom1; i <= entryCustom4; i++)
		if (!getField(i).isEmpty())
		{
			text += rtExpand(getField(i), richText);
			text += br;
		}
	text += ps;

	// category
	if (!getCategoryLabel().isEmpty())
	{
		text += par;
		text += rtExpand(getCategoryLabel(), richText);
		text += ps;
	}

	// note
	if (!getField(entryNote).isEmpty())
	{
		text += richText?CSL1("<hr/>"):CSL1("-----------------------------\n");
		text += par;
		text += rtExpand(getField(entryNote), richText);
		text += ps;
	}

	return text;
}

QString PilotAddress::getCategoryLabel() const
{
	int cat(getCat());
	if (cat>0) return codec()->toUnicode(fAppInfo.category.name[cat]);
	else return QString::null;
}

QStringList PilotAddress::getEmails() const
{
	FUNCTIONSETUP;
	QStringList list;
	QString test;

	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			if (ind == eEmail)
			{
				list.append(test);
			}
		}
	}

#ifdef DEBUG
	DEBUGDAEMON << fname << ": returning: ["
				<< list.size() << "] e-mail addresses." << endl;
#endif
	return list;
}

KABC::PhoneNumber::List PilotAddress::getPhoneNumbers() const
{
	FUNCTIONSETUP;

	KABC::PhoneNumber::List list;
	QString test;

	int shownPhone = getShownPhone() + entryPhone1;
#ifdef DEBUG
	DEBUGDAEMON << fname << ": preferred pilot index is: ["
				<< shownPhone << "], preferred phone number is: ["
				<< getField(shownPhone) << "]" << endl;
#endif

	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		// only look at this if the field is populated
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			// we only care about non-email types
			if (ind != eEmail)
			{
				int phoneType = pilotToPhoneMap[ind];

				// only populate a PhoneNumber if we have a corresponding type
				if (phoneType >=0)
				{
					// if this is the preferred phone number, set it as such
					if (shownPhone == i) {
						phoneType |= KABC::PhoneNumber::Pref;
#ifdef DEBUG
	DEBUGDAEMON << fname << ": found preferred pilot index: ["
				<< i << "], text: [" << test << "]" << endl;
#endif
					}
					KABC::PhoneNumber ph(test, phoneType);
					list.append(ph);
				} else {
#ifdef DEBUG
	DEBUGDAEMON << fname << ": whoopsie.  pilot phone number: ["
				<< test << "], index: [" << i << "], type: ["
				<< ind << "], has no corresponding PhoneNumber type." << endl;
#endif
				}
			}
		}
	}
#ifdef DEBUG
	DEBUGDAEMON << fname << ": returning: ["
				<< list.size() << "] phone numbers" << endl;
#endif
	return list;
}

void PilotAddress::setPhoneNumbers(KABC::PhoneNumber::List list)
{
	FUNCTIONSETUP;
	QString test;

	// clear all phone numbers (not e-mails) first
	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			if (ind != eEmail)
			{
				setField(i, "");
			}
		}
	}

	// now iterate through the list and for each PhoneNumber in the list,
	// iterate through our phone types using our map and set the first one
	// we find as the type of address for the Pilot
	QMap<int, int>::ConstIterator it;

	for(KABC::PhoneNumber::List::Iterator listIter = list.begin();
		   listIter != list.end(); ++listIter)
	{
		KABC::PhoneNumber phone = *listIter;

		int category = eHome;

		for ( it = pilotToPhoneMap.begin(); it != pilotToPhoneMap.end(); ++it )
		{
			int pilotKey = it.key();
			int phoneKey = it.data();
			if ( phone.type() & phoneKey)
			{
#ifdef DEBUG
	DEBUGDAEMON << fname << ": found pilot type: ["
				<< pilotKey << "] ("
				<< fAppInfo.phoneLabels[pilotKey]
				<< ") for PhoneNumber: ["
				<< phone.number() << "]" << endl;
#endif
				category = pilotKey;
				break;
			}
		}
		int fieldSlot = setPhoneField(static_cast<PilotAddress::EPhoneType>(category),
					  phone.number(), true, false);

		// if this is the preferred phone number, then set it as such
		if (phone.type() & KABC::PhoneNumber::Pref) {
#ifdef DEBUG
	DEBUGDAEMON << fname << ": found preferred PhoneNumber. "
				<< "setting showPhone to index: ["
				<< fieldSlot << "], PhoneNumber: ["
				<< phone.number() << "]" << endl;
#endif
			fAddressInfo.showPhone = fieldSlot - entryPhone1;
		}
	}
}

void PilotAddress::setEmails(QStringList list)
{
	QString test;

	// clear all e-mails first
	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			if (ind == eEmail)
			{
				setField(i, "");
			}
		}
	}

	for(QStringList::Iterator listIter = list.begin();
		   listIter != list.end(); ++listIter)
	{
		QString email = *listIter;
		setPhoneField(eEmail, email, true, false);<commit_msg>- trying really hard now to set a sensible preferred/showPhone for the   Pilot.  Previously, abbrowser-conduit used to blindly set it to the   mobile phone number.  This has resulted in 99% of the contacts in my   Pilot not showing any display number in the contact list.  Now, we'll try   to set it to something reasonable if it's either not set or if the field   it's set to is empty.<commit_after>/* KPilot
**
** Copyright (C) 1998-2001 by <NAME>
** Copyright (C) 2003-2004 <NAME> <<EMAIL>>
**
** This is a C++ wrapper for the pilot's address database structures.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to <EMAIL>
*/


static const char *pilotadress_id =
	"$Id$";

#ifndef _KPILOT_OPTIONS_H
#include "options.h"
#endif

#include <stdlib.h>
#include <assert.h>

#include <qtextcodec.h>
#include <qstringlist.h>

#include "pilotAddress.h"


#define MAXFIELDS 19

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo,
	PilotRecord * rec) :
	PilotAppCategory(rec),
	fAppInfo(appInfo),
	fAddressInfo()
{
	FUNCTIONSETUPL(4);
	if (rec) unpack_Address(&fAddressInfo, (unsigned char *) rec->getData(), rec->getLen());
	(void) pilotadress_id;
	_loadMaps();
}

PilotAddress::PilotAddress(struct AddressAppInfo &appInfo) :
	PilotAppCategory(),
	fAppInfo(appInfo)
{
	FUNCTIONSETUPL(4);
	reset();

	// assign the phoneLabel so it doesn't appear in the pilot as
	// work for all fields, but at least shows other fields
	fAddressInfo.phoneLabel[0] = (int) eWork;
	fAddressInfo.phoneLabel[1] = (int) eHome;
	fAddressInfo.phoneLabel[2] = (int) eOther;
	fAddressInfo.phoneLabel[3] = (int) eMobile;
	fAddressInfo.phoneLabel[4] = (int) eEmail;

	_loadMaps();
}

PilotAddress::PilotAddress(const PilotAddress & copyFrom) :
	PilotAppCategory(copyFrom),
	fAppInfo(copyFrom.fAppInfo),
	fAddressInfo()
{
	FUNCTIONSETUPL(4);
	_copyAddressInfo(copyFrom.fAddressInfo);

	_loadMaps();
}

PilotAddress & PilotAddress::operator = (const PilotAddress & copyFrom)
{
	FUNCTIONSETUPL(4);
	PilotAppCategory::operator = (copyFrom);
	_copyAddressInfo(copyFrom.fAddressInfo);
	return *this;
}

bool PilotAddress::operator==(const PilotAddress &compareTo)
{
	FUNCTIONSETUPL(4);
	// TODO: call == of PilotAppCategory. I don't think this is necessary, but I'm not so sure...
//	if (!(PilotAppCategory)(this)->operator==(compareTo) ) return false;

	// now compare all the fields stored in the fAddressInfo.entry array of char*[19]
	for (int i=0; i<MAXFIELDS; i++) {
		// if one is NULL, and the other non-empty, they are not equal for sure
		if ( !getFieldP(i) && compareTo.getFieldP(i)) return false;
		if ( getFieldP(i) && !compareTo.getFieldP(i)) return false;
		// test for getField(i)!=... to prevent strcmp or NULL strings!  None or both can be zero, but not a single one.
		if ( (getFieldP(i) != compareTo.getFieldP(i)) && ( strcmp(getFieldP(i), compareTo.getFieldP(i)) ) )  return false;
	}
	return true;
}


void PilotAddress::_copyAddressInfo(const struct Address &copyFrom)
{
	FUNCTIONSETUPL(4);
	fAddressInfo.showPhone = copyFrom.showPhone;

	for (int labelLp = 0; labelLp < 5; labelLp++)
	{
		fAddressInfo.phoneLabel[labelLp] =
			copyFrom.phoneLabel[labelLp];
	}

	for (int entryLp = 0; entryLp < MAXFIELDS; entryLp++)
	{
		if (copyFrom.entry[entryLp])
			fAddressInfo.entry[entryLp] =
				qstrdup(copyFrom.entry[entryLp]);
		else
			fAddressInfo.entry[entryLp] = 0L;
	}
}


PilotAddress::~PilotAddress()
{
	FUNCTIONSETUPL(4);
	free_Address(&fAddressInfo);
}

QString PilotAddress::getTextRepresentation(bool richText)
{
	QString text, tmp;

	QString par = richText?CSL1("<p>"):CSL1("");
	QString ps = richText?CSL1("</p>"):CSL1("\n");
	QString br = richText?CSL1("<br/>"):CSL1("\n");

	// title + name
	text += par;
	if (!getField(entryTitle).isEmpty())
	{
		text += rtExpand(getField(entryTitle), richText);
		text += CSL1(" ");
	}

	tmp = richText?CSL1("<b><big>%1%2%3</big></b>"):CSL1("%1%2%3");
	if (!getField(entryFirstname).isEmpty())
		tmp=rtExpand(tmp.arg(getField(entryFirstname)), richText).arg(CSL1(" "));
	else
		tmp=tmp.arg(CSL1(" ")).arg(CSL1(" "));
	tmp=tmp.arg(rtExpand(getField(entryLastname), richText));
	text += tmp;
	text += ps;

	// company
	if (!getField(entryCompany).isEmpty())
	{
		text += par;
		text += rtExpand(getField(entryCompany), richText);
		text += ps;
	}

	// phone numbers (+ labels)
	text += par;
	for (int i = entryPhone1; i <= entryPhone5; i++)
		if (!getField(i).isEmpty())
		{
			if (richText)
			{
				if (getShownPhone() == i - entryPhone1)
					tmp=CSL1("<small>%1: </small><b>%2</b>");
				else
					tmp=CSL1("<small>%1: </small>%2");
			}
			else
				tmp=CSL1("%1: %2");
			tmp=tmp.arg(PilotAppCategory::codec()->toUnicode(
				fAppInfo.phoneLabels[getPhoneLabelIndex(i-entryPhone1)]));
			tmp=tmp.arg(rtExpand(getField(i), richText));
			text += tmp;
			text += br;
		}
	text += ps;

	// address, city, state, country
	text += par;
	if (!getField(entryAddress).isEmpty())
	{
		text += rtExpand(getField(entryAddress), richText);
		text += br;
	}
	if (!getField(entryCity).isEmpty())
	{
		text += rtExpand(getField(entryCity), richText);
		text += CSL1(" ");
	}
	if (!getField(entryState).isEmpty())
	{
		text += rtExpand(getField(entryState), richText);
		text += CSL1(" ");
	}
	if (!getField(entryZip).isEmpty())
	{
		text += rtExpand(getField(entryZip), richText);
	}
	text += br;
	if (!getField(entryCountry).isEmpty())
	{
		text += rtExpand(getField(entryCountry), richText);
		text += br;
	}
	text += ps;

	// custom fields
	text += par;
	for (int i = entryCustom1; i <= entryCustom4; i++)
		if (!getField(i).isEmpty())
		{
			text += rtExpand(getField(i), richText);
			text += br;
		}
	text += ps;

	// category
	if (!getCategoryLabel().isEmpty())
	{
		text += par;
		text += rtExpand(getCategoryLabel(), richText);
		text += ps;
	}

	// note
	if (!getField(entryNote).isEmpty())
	{
		text += richText?CSL1("<hr/>"):CSL1("-----------------------------\n");
		text += par;
		text += rtExpand(getField(entryNote), richText);
		text += ps;
	}

	return text;
}

QString PilotAddress::getCategoryLabel() const
{
	int cat(getCat());
	if (cat>0) return codec()->toUnicode(fAppInfo.category.name[cat]);
	else return QString::null;
}

QStringList PilotAddress::getEmails() const
{
	FUNCTIONSETUP;
	QStringList list;
	QString test;

	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			if (ind == eEmail)
			{
				list.append(test);
			}
		}
	}

#ifdef DEBUG
	DEBUGDAEMON << fname << ": returning: ["
				<< list.size() << "] e-mail addresses." << endl;
#endif
	return list;
}

KABC::PhoneNumber::List PilotAddress::getPhoneNumbers() const
{
	FUNCTIONSETUP;

	KABC::PhoneNumber::List list;
	QString test;

	int shownPhone = getShownPhone() + entryPhone1;
#ifdef DEBUG
	DEBUGDAEMON << fname << ": preferred pilot index is: ["
				<< shownPhone << "], preferred phone number is: ["
				<< getField(shownPhone) << "]" << endl;
#endif

	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		// only look at this if the field is populated
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			// we only care about non-email types
			if (ind != eEmail)
			{
				int phoneType = pilotToPhoneMap[ind];

				// only populate a PhoneNumber if we have a corresponding type
				if (phoneType >=0)
				{
					// if this is the preferred phone number, set it as such
					if (shownPhone == i) {
						phoneType |= KABC::PhoneNumber::Pref;
#ifdef DEBUG
	DEBUGDAEMON << fname << ": found preferred pilot index: ["
				<< i << "], text: [" << test << "]" << endl;
#endif
					}
					KABC::PhoneNumber ph(test, phoneType);
					list.append(ph);
				} else {
#ifdef DEBUG
	DEBUGDAEMON << fname << ": whoopsie.  pilot phone number: ["
				<< test << "], index: [" << i << "], type: ["
				<< ind << "], has no corresponding PhoneNumber type." << endl;
#endif
				}
			}
		}
	}
#ifdef DEBUG
	DEBUGDAEMON << fname << ": returning: ["
				<< list.size() << "] phone numbers" << endl;
#endif
	return list;
}

void PilotAddress::setPhoneNumbers(KABC::PhoneNumber::List list)
{
	FUNCTIONSETUP;
	QString test;

	// clear all phone numbers (not e-mails) first
	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			if (ind != eEmail)
			{
				setField(i, "");
			}
		}
	}

	// now iterate through the list and for each PhoneNumber in the list,
	// iterate through our phone types using our map and set the first one
	// we find as the type of address for the Pilot
	QMap<int, int>::ConstIterator it;

	for(KABC::PhoneNumber::List::Iterator listIter = list.begin();
		   listIter != list.end(); ++listIter)
	{
		KABC::PhoneNumber phone = *listIter;

		int category = eHome;

		for ( it = pilotToPhoneMap.begin(); it != pilotToPhoneMap.end(); ++it )
		{
			int pilotKey = it.key();
			int phoneKey = it.data();
			if ( phone.type() & phoneKey)
			{
#ifdef DEBUG
	DEBUGDAEMON << fname << ": found pilot type: ["
				<< pilotKey << "] ("
				<< fAppInfo.phoneLabels[pilotKey]
				<< ") for PhoneNumber: ["
				<< phone.number() << "]" << endl;
#endif
				category = pilotKey;
				break;
			}
		}
		int fieldSlot = setPhoneField(static_cast<PilotAddress::EPhoneType>(category),
					  phone.number(), true, false);

		// if this is the preferred phone number, then set it as such
		if (phone.type() & KABC::PhoneNumber::Pref) {
#ifdef DEBUG
	DEBUGDAEMON << fname << ": found preferred PhoneNumber. "
				<< "setting showPhone to index: ["
				<< fieldSlot << "], PhoneNumber: ["
				<< phone.number() << "]" << endl;
#endif
			fAddressInfo.showPhone = fieldSlot - entryPhone1;
		}
	}

#ifdef DEBUG
	DEBUGDAEMON << fname << ": Pilot's showPhone now: ["
				<< fAddressInfo.showPhone << "]." << endl;
#endif

	// after setting the numbers, make sure that something sensible is set as the
	// shownPhone on the Pilot if nothing is yet...
	QString pref = getField(fAddressInfo.showPhone + entryPhone1);
	if (fAddressInfo.showPhone < 0 || fAddressInfo.showPhone > 4 || pref.isEmpty()) {
#ifdef DEBUG
	DEBUGDAEMON << fname << ": Pilot's showPhone: ["
				<< fAddressInfo.showPhone
				<< "] not properly set to a default. trying to set a sensible one."
				<< endl;
#endif
		for (int i = entryPhone1; i <= entryPhone5; i++)
		{
			pref = getField(i);
			if (!pref.isEmpty())
			{
				fAddressInfo.showPhone = i - entryPhone1;
				break;
			}
		}
	}
#ifdef DEBUG
	DEBUGDAEMON << fname << ": Pilot's showPhone now: ["
				<< fAddressInfo.showPhone << "], and that's final." << endl;
#endif
}

void PilotAddress::setEmails(QStringList list)
{
	QString test;

	// clear all e-mails first
	for (int i = entryPhone1; i <= entryPhone5; i++)
	{
		test = getField(i);
		if (!test.isEmpty())
		{
			int ind = getPhoneLabelIndex(i-entryPhone1);
			if (ind == eEmail)
			{
				setField(i, "");
			}
		}
	}

	for(QStringList::Iterator listIter = list.begin();
		   listIter != list.end(); ++listIter)
	{
		QString email = *listIter;
		setPhoneField(eEmail, email, true, false);
{'fraction_non_alphanumeric': 0.16046087459406558, 'fraction_numerical': 0.00978691222919169, 'mean_word_length': 3.914735461303017, 'pattern_counts': {'":': 17, '<': 303, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4196703', 'n_tokens_mistral': 8646, 'n_tokens_neox': 7798, 'n_words': 2052}