1998-05-01 00:53:59 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*/
|
|
|
|
//
|
|
|
|
// mkabook.cpp -- Handles "addbook:" " URLs for core Navigator, without
|
|
|
|
// requiring libmsg. mkabook is intended for adding
|
|
|
|
// to the address-book.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
1998-05-19 04:54:09 +04:00
|
|
|
#include "mkutils.h"
|
1998-05-01 00:53:59 +04:00
|
|
|
|
1998-06-25 09:50:45 +04:00
|
|
|
#include "xp.h"
|
|
|
|
#include "xp_str.h"
|
|
|
|
|
1998-05-01 00:53:59 +04:00
|
|
|
#include "mkgeturl.h"
|
|
|
|
#include "mkabook.h"
|
|
|
|
#include "addrbook.h"
|
|
|
|
|
1998-06-25 09:50:45 +04:00
|
|
|
#include "abcom.h"
|
|
|
|
#include "xpgetstr.h"
|
|
|
|
#include "pw_public.h"
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
extern int MK_OUT_OF_MEMORY;
|
|
|
|
extern int MK_MALFORMED_URL_ERROR;
|
|
|
|
extern int MK_ADDR_IMPORT_CARDS;
|
|
|
|
extern int MK_ADDR_IMPORT_MAILINGLISTS;
|
|
|
|
extern int MK_ADDR_EXPORT_CARDS;
|
|
|
|
extern int MK_MSG_ADDRESS_BOOK;
|
|
|
|
extern int MK_ADDR_EXPORT_TITLE;
|
|
|
|
extern int MK_ADDR_IMPORT_TITLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
abImportVCard,
|
|
|
|
abImport,
|
|
|
|
abExport,
|
|
|
|
abCopy /* copying, deleting, moving address book entries */
|
|
|
|
} net_abUrlType;
|
|
|
|
|
|
|
|
class NET_AddressBookConnData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NET_AddressBookConnData (ActiveEntry * ce)
|
|
|
|
{
|
|
|
|
m_commandData = NULL;
|
|
|
|
m_addressBook = NULL;
|
|
|
|
m_urlType = abImportVCard;
|
|
|
|
m_started = FALSE;
|
|
|
|
m_ce = ce;
|
|
|
|
m_container = NULL;
|
|
|
|
|
|
|
|
// Netlib magic so we get a timeslice without waiting for a read-ready socket.
|
|
|
|
// It would be nice to ditch this, but the LDAP SDK manages the sockets.
|
|
|
|
if (m_ce)
|
|
|
|
{
|
|
|
|
m_ce->socket = NULL;
|
|
|
|
NET_SetCallNetlibAllTheTime(m_ce->window_id, "mkabook");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~NET_AddressBookConnData ()
|
|
|
|
{
|
|
|
|
if (m_container)
|
|
|
|
{
|
|
|
|
AB_ReleaseContainer(m_container);
|
|
|
|
m_container = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Netlib magic so we won't get called anymore for this URL
|
|
|
|
// It would be nice to ditch this, but the LDAP SDK manages the sockets.
|
|
|
|
NET_ClearCallNetlibAllTheTime(m_ce->window_id, "mkabook");
|
|
|
|
m_ce = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MOZ_NEWADDR
|
|
|
|
virtual int Interrupt() = 0;
|
|
|
|
virtual int Process() = 0;
|
|
|
|
virtual int Load() = 0;
|
|
|
|
#else
|
|
|
|
virtual int Interrupt() {return 0;}
|
|
|
|
virtual int Process() { return 0;}
|
|
|
|
virtual int Load() {return 0;}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef MOZ_NEWADDR
|
|
|
|
virtual int Initialize(const char * url) {return 0;}
|
|
|
|
#else
|
|
|
|
XP_Bool Initialize(const char *url) { return FALSE;}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
void *m_cookie;
|
|
|
|
char *m_commandData;
|
|
|
|
ABook *m_addressBook; // only used by old address book APIs....remove when everyone is using the new APIs...
|
|
|
|
ActiveEntry *m_ce;
|
|
|
|
AB_ContainerInfo * m_container;
|
|
|
|
|
|
|
|
net_abUrlType m_urlType;
|
|
|
|
XP_Bool m_started;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
The connection data class for importing a vcard URL into an address book. This operation is
|
|
|
|
actually a synchronous so we shouldn't have to fill in implementations for interrupt...
|
|
|
|
***********************************************************************************************/
|
|
|
|
class net_AddressBookAddVCard : public NET_AddressBookConnData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
net_AddressBookAddVCard(ActiveEntry * ce);
|
|
|
|
virtual ~net_AddressBookAddVCard();
|
|
|
|
|
|
|
|
virtual int Load();
|
|
|
|
virtual int Process();
|
|
|
|
virtual int Initialize(const char * url);
|
|
|
|
virtual int Interrupt();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
int LoadContainerToAddTo();
|
|
|
|
};
|
|
|
|
|
|
|
|
net_AddressBookAddVCard::net_AddressBookAddVCard(ActiveEntry *ce) : NET_AddressBookConnData(ce)
|
|
|
|
{
|
|
|
|
m_urlType = abImportVCard;
|
|
|
|
}
|
|
|
|
|
|
|
|
net_AddressBookAddVCard::~net_AddressBookAddVCard()
|
|
|
|
{}
|
|
|
|
|
|
|
|
int net_AddressBookAddVCard::LoadContainerToAddTo()
|
|
|
|
{
|
|
|
|
// acquire list of personal address books, then grab the first one...
|
|
|
|
XP_List * containers = AB_AcquireAddressBookContainers(m_ce->window_id);
|
|
|
|
if (containers)
|
|
|
|
{
|
|
|
|
// extract the first one
|
|
|
|
int index = 1;
|
|
|
|
m_container = NULL;
|
|
|
|
while (!m_container && index <= XP_ListCount(containers))
|
|
|
|
m_container = (AB_ContainerInfo *) XP_ListGetObjectNum (containers, index++);
|
|
|
|
if (m_container)
|
|
|
|
AB_AcquireContainer(m_container); // acquire our own ref count
|
|
|
|
|
|
|
|
AB_ReleaseContainersList(containers); // release ref count on all the ctrs
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookAddVCard::Load()
|
|
|
|
{
|
|
|
|
// load m_container...right now this is just the first address book available...
|
|
|
|
return LoadContainerToAddTo();
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookAddVCard::Process()
|
|
|
|
{
|
|
|
|
// since this is a synchronous operation, do the import...
|
|
|
|
int status = 0;
|
|
|
|
if (m_container)
|
|
|
|
status = AB_ImportVCards(m_container, m_commandData);
|
|
|
|
|
|
|
|
return MK_CONNECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookAddVCard::Interrupt()
|
|
|
|
{
|
|
|
|
XP_ASSERT(FALSE); // this should not happen because vcard happens synch....
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookAddVCard::Initialize(const char * url)
|
|
|
|
{
|
|
|
|
char *search = NET_ParseURL (url, GET_SEARCH_PART);
|
|
|
|
m_urlType = abImportVCard;
|
|
|
|
if (search)
|
|
|
|
{
|
|
|
|
m_commandData = XP_STRDUP (search + 7);
|
|
|
|
NET_UnEscape (m_commandData);
|
|
|
|
}
|
|
|
|
XP_FREEIF(search);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
All of our asynch operations in the new address book (export and import right now), use
|
|
|
|
progress windows. We use this class to pull out the progress window commonality between
|
|
|
|
export and import. net_AddressBookAsynchData handles creation and destruction of the
|
|
|
|
progress panes. We use virtual methods to determine the appropriate title and description
|
|
|
|
text for the progress windows
|
|
|
|
************************************************************************************************/
|
|
|
|
|
|
|
|
// call back function for canceling asynch operations...
|
|
|
|
static void CancelAsynch(void *closure)
|
|
|
|
{
|
|
|
|
MWContext *progressContext = (MWContext *)closure;
|
|
|
|
if (progressContext)
|
|
|
|
XP_InterruptContext(progressContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
class net_AddressBookAsynchData : public NET_AddressBookConnData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
net_AddressBookAsynchData(ActiveEntry * ce);
|
|
|
|
virtual ~net_AddressBookAsynchData();
|
|
|
|
|
|
|
|
// all address book connect data classes support Load, Process, Initialize and Interrupt
|
|
|
|
// as these 4 methods are called by the NET_ functions in mkabook.h
|
|
|
|
virtual int Load(); // creates progress windows...
|
|
|
|
|
|
|
|
virtual int Process() = 0;
|
|
|
|
virtual int Initialize(const char * url) = 0;
|
|
|
|
virtual int Interrupt() = 0;
|
|
|
|
|
|
|
|
// string functions used to build the progress window
|
|
|
|
virtual char * GetPWTitle() { return NULL;}
|
|
|
|
virtual char * GetPWLine1Text() { return NULL;} // caller must free this string...
|
|
|
|
virtual char * GetPWLine2Text() { return NULL;} // caller must free this string..
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// Some asynch urls use progress windows....
|
|
|
|
MWContext *m_progressContext;
|
|
|
|
pw_ptr m_progressWindow;
|
|
|
|
};
|
|
|
|
|
|
|
|
net_AddressBookAsynchData::net_AddressBookAsynchData(ActiveEntry * ce) : NET_AddressBookConnData(ce)
|
|
|
|
{
|
|
|
|
m_progressContext = NULL;
|
|
|
|
m_progressWindow = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
net_AddressBookAsynchData::~net_AddressBookAsynchData()
|
|
|
|
{
|
|
|
|
if (m_progressWindow)
|
|
|
|
{
|
|
|
|
PW_Hide(m_progressWindow);
|
|
|
|
PW_Destroy(m_progressWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_progressContext)
|
|
|
|
PW_DestroyProgressContext(m_progressContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookAsynchData::Load()
|
|
|
|
{
|
|
|
|
int status = 0;
|
|
|
|
// get m_container from the url struct...
|
|
|
|
if (m_ce && m_ce->URL_s)
|
|
|
|
m_container = (AB_ContainerInfo *)m_ce->URL_s->owner_data; // it was already acquired when it was inserted into the url_struct...
|
|
|
|
|
|
|
|
if (m_container)
|
|
|
|
{
|
|
|
|
m_progressContext = PW_CreateProgressContext();
|
|
|
|
if (m_progressContext)
|
|
|
|
{
|
|
|
|
m_progressWindow = PW_Create(NULL, pwStandard);
|
|
|
|
if (m_progressWindow)
|
|
|
|
{
|
|
|
|
PW_AssociateWindowWithContext(m_progressContext, m_progressWindow);
|
|
|
|
char * title = GetPWTitle();
|
|
|
|
char * line1Text = GetPWLine1Text();
|
|
|
|
char * line2Text = GetPWLine2Text();
|
|
|
|
|
|
|
|
// it is okay to set a NULL title or line...
|
|
|
|
PW_SetWindowTitle(m_progressWindow, title); // resource string
|
|
|
|
PW_SetLine1(m_progressWindow, line1Text);// do we want anything here?
|
|
|
|
PW_SetLine2(m_progressWindow, line2Text); // mscott: again...add a real resource string for this
|
|
|
|
PW_SetProgressRange(m_progressWindow,0,100);
|
|
|
|
PW_SetCancelCallback(m_progressWindow, CancelAsynch, m_ce->window_id);
|
|
|
|
PW_Show(m_progressWindow);
|
|
|
|
|
|
|
|
// free any allocated strings
|
|
|
|
XP_FREEIF(line1Text);
|
|
|
|
XP_FREEIF(line2Text);
|
|
|
|
XP_FREEIF(title);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PW_DestroyProgressContext(m_progressContext);
|
|
|
|
} // if context
|
|
|
|
} // if container
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
The connection data class for copying/moving entries between address books. This operation is
|
|
|
|
asynch. We assume that the AB_AddressCopyInfo struct for the transfer is stored in the owner_data
|
|
|
|
field of the url_struct. In addition, status information will be shown through the current event's
|
|
|
|
context.
|
|
|
|
***********************************************************************************************/
|
|
|
|
class net_AddressBookCopy : public net_AddressBookAsynchData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
net_AddressBookCopy(ActiveEntry * ce);
|
|
|
|
virtual ~net_AddressBookCopy();
|
|
|
|
|
|
|
|
virtual int Load();
|
|
|
|
virtual int Process();
|
|
|
|
virtual int Initialize(const char * url);
|
|
|
|
virtual int Interrupt();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// any state we may ned to store...
|
|
|
|
AB_AddressBookCopyInfo * m_abCopyInfo;
|
|
|
|
};
|
|
|
|
|
|
|
|
net_AddressBookCopy::net_AddressBookCopy(ActiveEntry * ce) : net_AddressBookAsynchData(ce)
|
|
|
|
{
|
|
|
|
if (ce && ce->URL_s)
|
|
|
|
m_abCopyInfo = (AB_AddressBookCopyInfo *) ce->URL_s->owner_data;
|
|
|
|
else
|
|
|
|
m_abCopyInfo = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
net_AddressBookCopy::~net_AddressBookCopy()
|
|
|
|
{
|
|
|
|
if (m_abCopyInfo)
|
|
|
|
XP_ASSERT(FALSE); // struct should have been released by finish or interrupt calls...
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookCopy::Load() // over ride this from base class so we don't create the progress window...
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookCopy::Initialize(const char * /* url */)
|
|
|
|
{
|
|
|
|
// we don't have any command data for address book copy urls....
|
|
|
|
m_urlType = abCopy;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookCopy::Process()
|
|
|
|
{
|
|
|
|
int status = 0;
|
|
|
|
XP_Bool copyFinished = FALSE;
|
|
|
|
if (m_abCopyInfo)
|
|
|
|
{
|
|
|
|
if (!m_started) // if we haven't begun the copy...use the begin APIs...
|
|
|
|
status = AB_BeginEntryCopy (m_abCopyInfo->srcContainer, m_ce->window_id, m_abCopyInfo, &m_cookie, ©Finished);
|
|
|
|
else // otherwise do more...
|
|
|
|
status = AB_MoreEntryCopy (m_abCopyInfo->srcContainer, m_ce->window_id, m_abCopyInfo, &m_cookie, ©Finished);
|
|
|
|
|
|
|
|
if (status != AB_SUCCESS) // then mark ourselves as finished!
|
|
|
|
{
|
|
|
|
XP_ASSERT(FALSE); // what condition failed to cause us to be here??
|
|
|
|
copyFinished = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// all progress is handled by the src container
|
|
|
|
|
|
|
|
if (copyFinished) // if we are finished,
|
|
|
|
{
|
|
|
|
AB_FinishEntryCopy(m_abCopyInfo->srcContainer, m_ce->window_id, m_abCopyInfo, &m_cookie); // clean up everything..
|
|
|
|
m_abCopyInfo = NULL;
|
|
|
|
status = MK_CONNECTED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
status = MK_WAITING_FOR_CONNECTION;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
status = MK_CONNECTED; // this copy is done...we didn't have a copy info struct!!!!
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookCopy::Interrupt()
|
|
|
|
{
|
|
|
|
// we are shutting down...
|
|
|
|
if (m_abCopyInfo)
|
|
|
|
AB_InterruptEntryCopy(m_abCopyInfo->srcContainer, m_ce->window_id, m_abCopyInfo, &m_cookie);
|
|
|
|
|
|
|
|
m_abCopyInfo = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
The connection data class for import. Importing in the new address book is asynch. The
|
|
|
|
file to import is contained in the URL. However, the particular address book to import into
|
|
|
|
is stored in the owner_data field of the URL struct which is in the active entry. When the
|
|
|
|
URL_struct is created, the container was reference counted. So when you are done importing,
|
|
|
|
or if importing is canceled, we are now responsible for releasing the reference count
|
|
|
|
on the container.
|
|
|
|
|
|
|
|
m_cookie is actually a struct which represents the import state for the container. When the
|
|
|
|
import is finished or interrupted, the container will free this cookie struct...
|
|
|
|
************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
class net_AddressBookImport : public net_AddressBookAsynchData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
net_AddressBookImport(ActiveEntry * ce);
|
|
|
|
virtual ~net_AddressBookImport();
|
|
|
|
|
|
|
|
// leave it to the subclass to implement these..
|
|
|
|
virtual int Process();
|
|
|
|
virtual int Initialize(const char * url);
|
|
|
|
virtual int Interrupt();
|
|
|
|
|
|
|
|
int UpdateProgress();
|
|
|
|
|
|
|
|
// string functions used to build the progress window
|
|
|
|
virtual char * GetPWTitle();
|
|
|
|
virtual char * GetPWLine1Text(); // caller must free this string...
|
|
|
|
virtual char * GetPWLine2Text(); // caller must free this string..
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// import in the new address book is asynch..we need a progress window to show it off....
|
|
|
|
uint32 m_passCount; // importing LDIF requires 2 passes....we want to keep track of which pass we are on for progress purposes...
|
|
|
|
};
|
|
|
|
|
|
|
|
net_AddressBookImport::net_AddressBookImport(ActiveEntry * ce) : net_AddressBookAsynchData(ce)
|
|
|
|
{
|
|
|
|
m_passCount = 1; // always start with first pass...
|
|
|
|
}
|
|
|
|
|
|
|
|
net_AddressBookImport::~net_AddressBookImport()
|
|
|
|
{
|
|
|
|
if (m_cookie)
|
|
|
|
XP_ASSERT(FALSE); // should have been freed and cleared by container import code....
|
|
|
|
|
|
|
|
// container is released by base class...
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookImport::Initialize(const char * url)
|
|
|
|
{
|
|
|
|
char * search = NET_ParseURL(url, GET_SEARCH_PART);
|
|
|
|
|
|
|
|
m_urlType = abImport;
|
|
|
|
m_commandData = XP_STRDUP(search+6);
|
|
|
|
NET_UnEscape(m_commandData);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char * net_AddressBookImport::GetPWTitle()
|
|
|
|
{
|
|
|
|
return XP_STRDUP(XP_GetString(MK_ADDR_IMPORT_TITLE));
|
|
|
|
}
|
|
|
|
|
|
|
|
char * net_AddressBookImport::GetPWLine1Text()
|
|
|
|
{
|
|
|
|
return NULL; // no line 1 text for import pane
|
|
|
|
}
|
|
|
|
|
|
|
|
char * net_AddressBookImport::GetPWLine2Text()
|
|
|
|
{
|
|
|
|
AB_ContainerAttribValue * attrib = NULL;
|
|
|
|
AB_GetContainerAttribute(m_container, attribName, &attrib);
|
|
|
|
|
|
|
|
char * lineText = NULL;
|
|
|
|
if (m_passCount <= 1)
|
|
|
|
{
|
|
|
|
if (attrib->u.string)
|
|
|
|
lineText = PR_smprintf (XP_GetString(MK_ADDR_IMPORT_CARDS), attrib->u.string);
|
|
|
|
else
|
|
|
|
lineText = PR_smprintf (XP_GetString(MK_ADDR_IMPORT_CARDS),XP_GetString(MK_MSG_ADDRESS_BOOK));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (attrib->u.string)
|
|
|
|
lineText = PR_smprintf (XP_GetString(MK_ADDR_IMPORT_MAILINGLISTS), attrib->u.string);
|
|
|
|
else
|
|
|
|
lineText = PR_smprintf (XP_GetString(MK_ADDR_IMPORT_MAILINGLISTS), XP_GetString(MK_MSG_ADDRESS_BOOK));
|
|
|
|
}
|
|
|
|
|
|
|
|
AB_FreeContainerAttribValue(attrib);
|
|
|
|
|
|
|
|
return lineText;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int net_AddressBookImport::Process()
|
|
|
|
{
|
|
|
|
int status = 0;
|
|
|
|
XP_Bool importFinished;
|
|
|
|
if (!m_started) // if we haven't begun the import...use the begin APIs...
|
|
|
|
status = AB_ImportBegin (m_container, NULL, m_commandData /* file name */, &m_cookie /* import state */, &importFinished);
|
|
|
|
else // otherwise do more...
|
|
|
|
status = AB_ImportMore (m_container, &m_cookie, &importFinished);
|
|
|
|
|
|
|
|
UpdateProgress();
|
|
|
|
|
|
|
|
// are we done?
|
|
|
|
if (importFinished) // if we are finished,
|
|
|
|
{
|
|
|
|
AB_ImportFinish(m_container, &m_cookie);
|
|
|
|
status = MK_CONNECTED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
status = MK_WAITING_FOR_CONNECTION;
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookImport::UpdateProgress ()
|
|
|
|
{
|
|
|
|
// now update progress bar...
|
|
|
|
uint32 position = 0; // position in the import file
|
|
|
|
uint32 fileLength = 0;
|
|
|
|
uint32 passCount = m_passCount;
|
|
|
|
int status = AB_ImportProgress(m_container, m_cookie, &position, &fileLength, &passCount);
|
|
|
|
if (passCount != m_passCount)
|
|
|
|
{
|
|
|
|
m_passCount = passCount;
|
|
|
|
char * text = GetPWLine1Text();
|
|
|
|
PW_SetLine1(m_progressWindow, text); // mscott: again...add a real resource string for this
|
|
|
|
XP_FREEIF(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fileLength)
|
|
|
|
{
|
|
|
|
int32 percent = (position * 100) / fileLength;
|
|
|
|
PW_SetProgressValue(m_progressWindow, percent);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookImport::Interrupt()
|
|
|
|
{
|
|
|
|
// we are shutting down...
|
|
|
|
AB_ImportInterrupt(m_container, &m_cookie); // destroys the container...
|
|
|
|
m_cookie = NULL;
|
|
|
|
// destruction will clean up the progress pane stuff...
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
|
|
The connection data class for export. Exporting in the new address book is asynch. The
|
|
|
|
file to export to is contained in the URL. However, the particular address book to export from
|
|
|
|
is stored in the owner_data field of the URL struct which is in the active entry. When the
|
|
|
|
URL_struct is created, the container was reference counted. So when you are done exporting,
|
|
|
|
or if export is canceled, we are responsible for releasing the reference count
|
|
|
|
on the container.
|
|
|
|
|
|
|
|
m_cookie is actually a struct which represents the export state for the container. When the
|
|
|
|
export is finished or interrupted, the container will free this cookie struct...
|
|
|
|
************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
class net_AddressBookExport : public net_AddressBookAsynchData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
net_AddressBookExport(ActiveEntry * ce);
|
|
|
|
virtual ~net_AddressBookExport();
|
|
|
|
|
|
|
|
virtual int Process();
|
|
|
|
virtual int Initialize(const char * url);
|
|
|
|
virtual int Interrupt();
|
|
|
|
|
|
|
|
int UpdateProgress();
|
|
|
|
|
|
|
|
// string functions used to build the progress window
|
|
|
|
virtual char * GetPWTitle();
|
|
|
|
virtual char * GetPWLine1Text(); // caller must free this string...
|
|
|
|
virtual char * GetPWLine2Text(); // caller must free this string..
|
|
|
|
|
|
|
|
protected:
|
|
|
|
};
|
|
|
|
|
|
|
|
net_AddressBookExport::net_AddressBookExport(ActiveEntry * ce) : net_AddressBookAsynchData(ce)
|
|
|
|
{}
|
|
|
|
|
|
|
|
net_AddressBookExport::~net_AddressBookExport()
|
|
|
|
{
|
|
|
|
if (m_cookie)
|
|
|
|
XP_ASSERT(FALSE); // should have been freed and cleared by container import code....
|
|
|
|
|
|
|
|
// container is released by base class...
|
|
|
|
// progress window is destroyed by base class..
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookExport::Initialize(const char * url)
|
|
|
|
{
|
|
|
|
char * search = NET_ParseURL(url, GET_SEARCH_PART);
|
|
|
|
m_urlType = abExport;
|
|
|
|
m_commandData = XP_STRDUP(search+6); // + 6 to skip over the "?file=" part
|
|
|
|
NET_UnEscape(m_commandData);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char * net_AddressBookExport::GetPWTitle()
|
|
|
|
{
|
|
|
|
return XP_STRDUP(XP_GetString(MK_ADDR_EXPORT_TITLE));
|
|
|
|
}
|
|
|
|
|
|
|
|
char * net_AddressBookExport::GetPWLine1Text()
|
|
|
|
{
|
|
|
|
return NULL; // no line 1 text for import pane
|
|
|
|
}
|
|
|
|
|
|
|
|
char * net_AddressBookExport::GetPWLine2Text()
|
|
|
|
{
|
|
|
|
AB_ContainerAttribValue * attrib = NULL;
|
|
|
|
AB_GetContainerAttribute(m_container, attribName, &attrib);
|
|
|
|
|
|
|
|
char * lineText = NULL;
|
|
|
|
if (attrib->u.string)
|
|
|
|
lineText = PR_smprintf (XP_GetString(MK_ADDR_EXPORT_CARDS), attrib->u.string);
|
|
|
|
else
|
|
|
|
lineText = PR_smprintf (XP_GetString(MK_ADDR_EXPORT_CARDS),XP_GetString(MK_MSG_ADDRESS_BOOK));
|
|
|
|
AB_FreeContainerAttribValue(attrib);
|
|
|
|
|
|
|
|
return lineText;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookExport::Process()
|
|
|
|
{
|
|
|
|
int status = 0;
|
|
|
|
XP_Bool exportFinished;
|
|
|
|
if (!m_started) // if we haven't begun the import...use the begin APIs...
|
|
|
|
status = AB_ExportBegin (m_container, NULL, m_commandData /* file name */, &m_cookie /* import state */, &exportFinished);
|
|
|
|
else // otherwise do more...
|
|
|
|
status = AB_ExportMore (m_container, &m_cookie, &exportFinished);
|
|
|
|
|
|
|
|
UpdateProgress();
|
|
|
|
|
|
|
|
// are we done?
|
|
|
|
if (exportFinished) // if we are finished,
|
|
|
|
{
|
|
|
|
AB_ExportFinish(m_container, &m_cookie);
|
|
|
|
status = MK_CONNECTED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
status = MK_WAITING_FOR_CONNECTION;
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookExport::UpdateProgress ()
|
|
|
|
{
|
|
|
|
// now update progress bar...
|
|
|
|
uint32 numberExported = 0;
|
|
|
|
uint32 totalEntries = 0;
|
|
|
|
|
|
|
|
int status = AB_ExportProgress(m_container, m_cookie, &numberExported, &totalEntries);
|
|
|
|
|
|
|
|
if (totalEntries)
|
|
|
|
{
|
|
|
|
int32 percent = (numberExported * 100) / totalEntries;
|
|
|
|
PW_SetProgressValue(m_progressWindow, percent);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int net_AddressBookExport::Interrupt()
|
|
|
|
{
|
|
|
|
// we are shutting down...
|
|
|
|
AB_ExportInterrupt(m_container, &m_cookie); // destroys the container...
|
|
|
|
m_cookie = NULL;
|
|
|
|
// destruction will clean up the progress pane stuff...
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-05-01 00:53:59 +04:00
|
|
|
//
|
|
|
|
// Callbacks from NET_GetURL
|
|
|
|
//
|
1998-06-25 09:50:45 +04:00
|
|
|
#ifdef MOZ_NEWADDR
|
|
|
|
|
|
|
|
extern "C" int32 net_ProcessAddressBook (ActiveEntry *ce)
|
|
|
|
{
|
|
|
|
int status = 0;
|
|
|
|
NET_AddressBookConnData *cd = (NET_AddressBookConnData*) ce->con_data;
|
|
|
|
if (cd)
|
|
|
|
{
|
|
|
|
status = cd->Process(); // should return MK_WAITING_FOR_CONNECTION
|
|
|
|
cd->m_started = TRUE;
|
|
|
|
if (status < 0 || status == MK_CONNECTED)
|
|
|
|
{
|
|
|
|
delete cd;
|
|
|
|
ce->con_data = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(status == MK_CONNECTED) // i don't understand why mkgeturl won't end the url on MK_CONNECTED, but it doesn't...
|
|
|
|
status = -1;
|
|
|
|
|
|
|
|
ce->status = status;
|
|
|
|
return ce->status;
|
|
|
|
}
|
1998-05-01 00:53:59 +04:00
|
|
|
|
|
|
|
extern "C" int32 net_AddressBookLoad (ActiveEntry *ce)
|
|
|
|
{
|
1998-06-25 09:50:45 +04:00
|
|
|
ce->status = -1;
|
|
|
|
int status = ce->status;
|
|
|
|
// examine URL to determine what type of connection data we need to create...
|
1998-05-01 00:53:59 +04:00
|
|
|
char * url = ce->URL_s->address;
|
1998-06-25 09:50:45 +04:00
|
|
|
char *path = NET_ParseURL (url, GET_PATH_PART);
|
1998-05-01 00:53:59 +04:00
|
|
|
char * search = NET_ParseURL(url, GET_SEARCH_PART);
|
1998-06-25 09:50:45 +04:00
|
|
|
NET_AddressBookConnData *cd = NULL;
|
|
|
|
switch (path[0])
|
|
|
|
{
|
|
|
|
case 'a':
|
|
|
|
case 'A':
|
|
|
|
if (!XP_STRNCASECMP(path,"add",3))
|
|
|
|
{
|
|
|
|
if (!XP_STRNCASECMP (search, "?vcard=", 7))
|
|
|
|
cd = new net_AddressBookAddVCard(ce);
|
|
|
|
if (!cd)
|
|
|
|
status = MK_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
XP_ASSERT(FALSE);
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
case 'I':
|
|
|
|
if (!XP_STRNCASECMP (path, "import", 6))
|
|
|
|
{
|
|
|
|
if (!XP_STRNCASECMP (search, "?file=", 6))
|
|
|
|
{
|
|
|
|
cd = new net_AddressBookImport(ce);
|
|
|
|
if (!cd)
|
|
|
|
status = MK_OUT_OF_MEMORY;
|
|
|
|
} //if ?file=...
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
if (!XP_STRNCASECMP (path, "export", 6))
|
|
|
|
{
|
|
|
|
if (!XP_STRNCASECMP (search, "?file=", 6))
|
|
|
|
{
|
|
|
|
cd = new net_AddressBookExport(ce);
|
|
|
|
if (!cd)
|
|
|
|
status = MK_OUT_OF_MEMORY;
|
|
|
|
} //if ?file=...
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
case 'C':
|
|
|
|
if (!XP_STRNCASECMP(path, "copy", 4))
|
|
|
|
{
|
|
|
|
// we have no search part on copy urls....
|
|
|
|
cd = new net_AddressBookCopy(ce);
|
|
|
|
if (!cd)
|
|
|
|
status = MK_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
status = MK_MALFORMED_URL_ERROR;
|
|
|
|
XP_ASSERT(FALSE);
|
|
|
|
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
|
|
|
|
1998-06-25 09:50:45 +04:00
|
|
|
ce->status = status; // catch any errors like MK_OUT_OF_MEMORY...
|
|
|
|
if (cd)
|
|
|
|
{
|
|
|
|
cd->Initialize(url);
|
|
|
|
cd->Load();
|
|
|
|
ce->con_data = cd; // store the connection data
|
|
|
|
ce->status = net_ProcessAddressBook (ce);
|
|
|
|
}
|
|
|
|
|
|
|
|
XP_FREEIF(path);
|
|
|
|
XP_FREEIF(search);
|
|
|
|
return ce->status;
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
|
|
|
|
1998-06-25 09:50:45 +04:00
|
|
|
extern "C" int32 net_InterruptAddressBook (ActiveEntry * ce)
|
|
|
|
{
|
|
|
|
ce->status = MK_INTERRUPTED;
|
|
|
|
NET_AddressBookConnData *cd = (NET_AddressBookConnData*) ce->con_data;
|
|
|
|
|
|
|
|
if (cd)
|
|
|
|
{
|
|
|
|
cd->Interrupt();
|
|
|
|
delete cd;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ce->status;
|
|
|
|
}
|
|
|
|
extern "C" void net_CleanupAddressBook(void)
|
|
|
|
{
|
|
|
|
// I'm not sure what cleanup stuff I have to do here...
|
|
|
|
// leaving it empty for now...
|
|
|
|
}
|
1998-05-01 00:53:59 +04:00
|
|
|
|
1998-06-25 09:50:45 +04:00
|
|
|
#else
|
1998-05-01 00:53:59 +04:00
|
|
|
extern "C" int32 net_ProcessAddressBook (ActiveEntry *ce)
|
|
|
|
{
|
1998-06-25 09:50:45 +04:00
|
|
|
NET_AddressBookConnData *cd = (NET_AddressBookConnData*) ce->con_data;
|
|
|
|
switch (cd->m_urlType)
|
|
|
|
{
|
|
|
|
case abImportVCard:
|
|
|
|
AB_ImportFromVcardURL(cd->m_addressBook, ce->window_id, cd->m_commandData); //mscott
|
|
|
|
ce->status = -1; //phil/mscott should work, but seems not to. MK_CONNECTED;
|
|
|
|
break;
|
|
|
|
case abImport:
|
|
|
|
if (!cd->m_started)
|
|
|
|
ce->status = MK_CONNECTED; //mscott AB_ImportBegin (cd->m_addressBook, ce->window_id, cd->m_commandData, &cd->m_cookie);
|
|
|
|
else
|
|
|
|
ce->status = MK_CONNECTED; //mscott AB_ImportMore (cd->m_addressBook, ce->window_id, cd->m_cookie);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
cd->m_started = TRUE;
|
|
|
|
|
|
|
|
// Either an error, or we're already done
|
|
|
|
if (ce->status != MK_WAITING_FOR_CONNECTION)
|
|
|
|
delete cd;
|
|
|
|
|
|
|
|
return ce->status;
|
1998-05-01 00:53:59 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
1998-06-25 09:50:45 +04:00
|
|
|
extern "C" int32 net_AddressBookLoad (ActiveEntry *ce)
|
1998-05-01 00:53:59 +04:00
|
|
|
{
|
1998-06-25 09:50:45 +04:00
|
|
|
ce->status = -1;
|
|
|
|
|
|
|
|
NET_AddressBookConnData *cd = new NET_AddressBookConnData(ce);
|
|
|
|
if (!cd)
|
|
|
|
return MK_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
ce->con_data = cd;
|
|
|
|
|
|
|
|
if (cd->Initialize (ce->URL_s->address))
|
|
|
|
ce->status = net_ProcessAddressBook(ce);
|
|
|
|
|
|
|
|
return ce->status;
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
net_CleanupAddressBook(void)
|
1998-06-25 09:50:45 +04:00
|
|
|
{}
|
|
|
|
|
|
|
|
extern "C" int32 net_InterruptAddressBook (ActiveEntry * ce)
|
1998-05-01 00:53:59 +04:00
|
|
|
{
|
1998-06-25 09:50:45 +04:00
|
|
|
ce->status = MK_INTERRUPTED;
|
|
|
|
NET_AddressBookConnData *cd = (NET_AddressBookConnData*) ce->con_data;
|
|
|
|
|
|
|
|
switch (cd->m_urlType)
|
|
|
|
{
|
|
|
|
case abImportVCard:
|
|
|
|
XP_ASSERT(FALSE); // this shouldn't happen because vCard import happens synchronously
|
|
|
|
break;
|
|
|
|
case abImport:
|
|
|
|
//mscott AB_ImportInterrupt (cd->m_addressBook, ce->window_id, cd->m_cookie);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
XP_ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete cd;
|
|
|
|
|
|
|
|
return ce->status;
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
1998-06-25 09:50:45 +04:00
|
|
|
#endif
|
1998-05-01 00:53:59 +04:00
|
|
|
|
|
|
|
MODULE_PRIVATE void
|
|
|
|
NET_InitAddressBookProtocol(void)
|
|
|
|
{
|
|
|
|
static NET_ProtoImpl abook_proto_impl;
|
|
|
|
|
|
|
|
abook_proto_impl.init = net_AddressBookLoad;
|
|
|
|
abook_proto_impl.process = net_ProcessAddressBook;
|
|
|
|
abook_proto_impl.interrupt = net_InterruptAddressBook;
|
|
|
|
abook_proto_impl.cleanup = net_CleanupAddressBook;
|
|
|
|
|
|
|
|
NET_RegisterProtocolImplementation(&abook_proto_impl, ADDRESS_BOOK_TYPE_URL);
|
|
|
|
}
|