fix 222774 import of mailing lists in outlook express address books doesn't populate the lists, r/sr=sspitzer, a=asa

This commit is contained in:
bienvenu%nventure.com 2005-04-15 15:21:19 +00:00
parent f2fd31b8de
commit e864f7750c
4 changed files with 484 additions and 364 deletions

View File

@ -364,12 +364,37 @@ HRESULT CWAB::IterateWABContents(CWabIterator *pIter, int *pDone)
//
if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_DISTLIST)
{
LPABCONT distListContainer = NULL;
// We will now take the entry-id of each object and cache it
// on the listview item representing that object. This enables
// us to uniquely identify the object later if we need to
//
hr = m_lpAdrBook->OpenEntry(cbEID, lpEID, NULL,
0,&ulObjType,(LPUNKNOWN *)&distListContainer);
LPMAPITABLE distListTable = NULL;
// Get a contents table of the dist list
//
hr = distListContainer->GetContentsTable( 0, &distListTable);
if (lpAB)
{
hr = distListTable->GetRowCount( 0, &rowCount);
if (HR_FAILED(hr))
rowCount = 100;
if (rowCount == 0)
rowCount = 1;
// Order the columns in the ContentsTable to conform to the
// ones we want - which are mainly DisplayName, EntryID and
// ObjectType
// The table is gauranteed to set the columns in the order
// requested
//
hr = distListTable->SetColumns( (LPSPropTagArray)&ptaEid, 0 );
CStrToUnicode( lpsz, uniStr);
keepGoing = pIter->EnumList( uniStr.get(), lpEID, cbEID);
keepGoing = pIter->EnumList( uniStr.get(), lpEID, cbEID, distListTable);
curCount++;
if (pDone) {
*pDone = (curCount * 100) / rowCount;
@ -377,6 +402,11 @@ HRESULT CWAB::IterateWABContents(CWabIterator *pIter, int *pDone)
*pDone = 100;
}
}
if (distListContainer)
distListContainer->Release();
if (distListTable)
distListTable->Release();
}
}
FreeProws(lpRowAB );
}

View File

@ -50,7 +50,7 @@
class CWabIterator {
public:
virtual nsresult EnumUser( const PRUnichar *pName, LPENTRYID pEid, ULONG cbEid) = 0;
virtual nsresult EnumList( const PRUnichar *pName, LPENTRYID pEid, ULONG cbEid) = 0;
virtual nsresult EnumList( const PRUnichar *pName, LPENTRYID pEid, ULONG cbEid, LPMAPITABLE lpTable) = 0;
};

View File

@ -64,6 +64,13 @@ typedef struct {
ULONG mapiTag;
} MAPIFields;
enum {
ieidPR_DISPLAY_NAME = 0,
ieidPR_ENTRYID,
ieidPR_OBJECT_TYPE,
ieidMax
};
/*
Fields in MAPI, not in Mozilla
PR_OFFICE_LOCATION
@ -112,30 +119,37 @@ nsOEAddressIterator::nsOEAddressIterator( CWAB *pWab, nsIAddrDatabase *database)
nsOEAddressIterator::~nsOEAddressIterator()
{
m_listRows.Reset();
NS_IF_RELEASE( m_database);
}
nsresult nsOEAddressIterator::EnumUser( const PRUnichar * pName, LPENTRYID pEid, ULONG cbEid)
{
IMPORT_LOG1( "User: %S\n", pName);
nsresult rv = NS_OK;
if (m_database) {
LPMAILUSER pUser = m_pWab->GetUser( cbEid, pEid);
if (pUser) {
// Get a new row from the database!
nsIMdbRow* newRow = nsnull;
rv = m_database->GetNewRow( &newRow);
nsCOMPtr <nsIMdbRow> newRow;
rv = m_database->GetNewRow(getter_AddRefs(newRow));
NS_ENSURE_SUCCESS(rv, rv);
// FIXME: Check with Candice about releasing the newRow if it
// isn't added to the database. Candice's code in nsAddressBook
// never releases it but that doesn't seem right to me!
if (newRow) {
if (BuildCard( pName, newRow, pUser)) {
if (newRow && BuildCard( pName, newRow, pUser))
{
rv = m_database->AddCardRowToDB(newRow);
NS_ENSURE_SUCCESS(rv, rv);
IMPORT_LOG0( "* Added entry to address book database\n");
nsString eMail;
LPSPropValue pProp = m_pWab->GetUserProperty( pUser, PR_EMAIL_ADDRESS);
if (pProp)
{
m_pWab->GetValueString( pProp, eMail);
SanitizeValue( eMail);
m_pWab->FreeProperty( pProp);
nsStringKey hashKey(eMail);
m_listRows.Put(&hashKey, newRow);
}
}
m_pWab->ReleaseUser( pUser);
@ -145,26 +159,102 @@ nsresult nsOEAddressIterator::EnumUser( const PRUnichar * pName, LPENTRYID pEid,
return(rv);
}
nsresult nsOEAddressIterator::EnumList( const PRUnichar * pName, LPENTRYID pEid, ULONG cbEid)
void nsOEAddressIterator::FindListRow(nsString &eMail, nsIMdbRow **cardRow)
{
nsStringKey hashKey(eMail);
*cardRow = (nsIMdbRow *) m_listRows.Get(&hashKey);
}
nsresult nsOEAddressIterator::EnumList( const PRUnichar * pName, LPENTRYID pEid, ULONG cbEid, LPMAPITABLE lpTable)
{
// If no name provided then we're done.
if (!pName || !(*pName))
return NS_OK;
nsresult rv = NS_ERROR_FAILURE;
HRESULT hr = E_FAIL;
// Make sure we have db to work with.
if (!m_database)
return rv;
nsCOMPtr <nsIMdbRow> newRow;
rv = m_database->GetNewListRow(getter_AddRefs(newRow));
nsCOMPtr <nsIMdbRow> listRow;
rv = m_database->GetNewListRow(getter_AddRefs(listRow));
NS_ENSURE_SUCCESS(rv, rv);
rv = m_database->AddListName(newRow, NS_ConvertUCS2toUTF8(pName).get());
rv = m_database->AddListName(listRow, NS_ConvertUCS2toUTF8(pName).get());
NS_ENSURE_SUCCESS(rv, rv);
rv = m_database->AddCardRowToDB(newRow);
rv = m_database->AddCardRowToDB(listRow);
NS_ENSURE_SUCCESS(rv, rv);
rv = m_database->AddListDirNode(newRow);
rv = m_database->AddListDirNode(listRow);
NS_ENSURE_SUCCESS(rv, rv);
LPSRowSet lpRowAB = NULL;
ULONG lpcbEID = 0;
LPENTRYID lpEID = NULL;
ULONG rowCount = 0;
int cNumRows = 0;
int numListElems = 0;
nsAutoString uniStr;
hr = lpTable->GetRowCount( 0, &rowCount);
//
hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL );
if(HR_FAILED(hr))
return NS_ERROR_FAILURE;
// Read all the rows of the table one by one
do
{
hr = lpTable->QueryRows(1, 0, &lpRowAB);
if(HR_FAILED(hr))
break;
if(lpRowAB)
{
cNumRows = lpRowAB->cRows;
if (cNumRows)
{
LPTSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA;
LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb;
ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb;
// There are 2 kinds of objects - the MAPI_MAILUSER contact object
// and the MAPI_DISTLIST contact object
// For distribution lists, we will only consider MAILUSER
// objects since we can't nest lists yet.
if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER)
{
LPMAILUSER pUser = m_pWab->GetUser( cbEID, lpEID);
LPSPropValue pProp = m_pWab->GetUserProperty( pUser, PR_EMAIL_ADDRESS);
nsString eMail;
nsCOMPtr <nsIMdbRow> cardRow;
m_pWab->GetValueString( pProp, eMail);
SanitizeValue( eMail);
FindListRow(eMail, getter_AddRefs(cardRow));
if (cardRow)
{
nsCOMPtr <nsIAbCard> userCard;
nsCOMPtr <nsIAbCard> newCard;
userCard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
m_database->InitCardFromRow(userCard,cardRow);
m_database->AddListCardColumnsToRow(userCard, listRow, ++numListElems,
getter_AddRefs(newCard),PR_TRUE);
}
m_pWab->FreeProperty( pProp);
m_pWab->ReleaseUser( pUser);
}
}
m_pWab->FreeProws(lpRowAB );
}
} while (SUCCEEDED(hr) && cNumRows && lpRowAB);
m_database->SetListAddressTotal(listRow, numListElems);
return rv;
}
@ -324,7 +414,5 @@ PRBool nsOEAddressIterator::BuildCard( const PRUnichar * pName, nsIMdbRow *newRo
NS_RELEASE( pFieldMap);
}
}
return( PR_TRUE);
}

View File

@ -42,6 +42,7 @@
#include "nsIAddrDatabase.h"
#include "mdb.h"
#include "nsString.h"
#include "nsHashtable.h"
class nsOEAddressIterator : public CWabIterator {
public:
@ -49,7 +50,8 @@ public:
~nsOEAddressIterator();
virtual nsresult EnumUser( const PRUnichar * pName, LPENTRYID pEid, ULONG cbEid);
virtual nsresult EnumList( const PRUnichar * pName, LPENTRYID pEid, ULONG cbEid);
virtual nsresult EnumList( const PRUnichar * pName, LPENTRYID pEid, ULONG cbEid, LPMAPITABLE table);
void FindListRow(nsString &eMail, nsIMdbRow **cardRow);
private:
PRBool BuildCard( const PRUnichar * pName, nsIMdbRow *card, LPMAILUSER pUser);
@ -58,7 +60,7 @@ private:
CWAB * m_pWab;
nsIAddrDatabase * m_database;
nsSupportsHashtable m_listRows;
};
#endif