Allow SeaMonkey to handle vCard attachments internally by launching a new address card dialog, also clean up the code to use a stream loader instead of implementing a new stream listener b=243733 r/sr=mscott

This commit is contained in:
neil%parkwaycc.co.uk 2004-07-06 14:06:45 +00:00
parent 78c0cca9f1
commit e7f8a10fbf
7 changed files with 49 additions and 157 deletions

View File

@ -210,6 +210,11 @@ static const nsModuleComponentInfo components[] =
NS_CONTENT_HANDLER_CONTRACTID_PREFIX"x-application-addvcard",
nsAddressBookConstructor },
{ "add vCard content handler",
NS_ADDRESSBOOK_CID,
NS_CONTENT_HANDLER_CONTRACTID_PREFIX"text/x-vcard",
nsAddressBookConstructor },
{ "The directory factory service interface",
NS_ABDIRFACTORYSERVICE_CID,
NS_ABDIRFACTORYSERVICE_CONTRACTID,

View File

@ -451,11 +451,4 @@
#define NS_MSGVCARDSERVICE_CONTRACTID \
"@mozilla.org/addressbook/msgvcardservice;1"
#define NS_MSGVCARDSTREAMLISTENER_CID \
{ 0xf4045da, 0x6187, 0x42ff, \
{ 0x9d, 0xf4, 0x80, 0x65, 0x44, 0xf, 0x76, 0x21 }}
#define NS_MSGVCARDSTREAMLISTENER_CONTRACTID \
"@mozilla.org/addressbook/msgvcardstreamlistener;1"
#endif // nsAbBaseCID_h__

View File

@ -86,8 +86,8 @@
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIDocShell.h"
#include "nsNetCID.h"
#include "nsIIOService.h"
#include "nsAutoPtr.h"
#include "nsIMsgVCardService.h"
// according to RFC 2849
// SEP = (CR LF / LF)
@ -177,7 +177,7 @@ nsAddressBook::~nsAddressBook()
NS_IMPL_THREADSAFE_ADDREF(nsAddressBook)
NS_IMPL_THREADSAFE_RELEASE(nsAddressBook)
NS_IMPL_QUERY_INTERFACE3(nsAddressBook, nsIAddressBook, nsICmdLineHandler, nsIContentHandler)
NS_IMPL_QUERY_INTERFACE4(nsAddressBook, nsIAddressBook, nsICmdLineHandler, nsIContentHandler, nsIStreamLoaderObserver)
//
// nsIAddressBook
@ -2081,19 +2081,11 @@ NS_IMETHODIMP nsAddressBook::HandleContent(const char * aContentType,
rv = channel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// create a stream listener to handle the v-card data
nsCOMPtr<nsIStreamListener> strListener = do_CreateInstance(NS_MSGVCARDSTREAMLISTENER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_WONT_HANDLE_CONTENT); // no registered v-card handler so just return that we won't handle the content
// create a new channel and run the url again
nsCOMPtr<nsIIOService> netService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
// create a stream loader to handle the v-card data
nsCOMPtr<nsIStreamLoader> streamLoader;
rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), uri, this, aWindowContext);
NS_ENSURE_SUCCESS(rv, rv);
rv = netService->NewChannelFromURI(uri, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
rv = channel->AsyncOpen(strListener, aWindowContext);
}
else // The content-type was not x-application-addvcard...
return NS_ERROR_WONT_HANDLE_CONTENT;
@ -2101,6 +2093,41 @@ NS_IMETHODIMP nsAddressBook::HandleContent(const char * aContentType,
return rv;
}
NS_IMETHODIMP nsAddressBook::OnStreamComplete(nsIStreamLoader *aLoader, nsISupports *aContext, nsresult aStatus, PRUint32 datalen, const PRUint8 *data)
{
NS_ENSURE_ARG_POINTER(aContext);
NS_ENSURE_SUCCESS(aStatus, aStatus); // don't process the vcard if we got a status error
nsresult rv = NS_OK;
// take our vCard string and open up an address book window based on it
nsCOMPtr<nsIMsgVCardService> vCardService = do_GetService(NS_MSGVCARDSERVICE_CONTRACTID);
if (vCardService)
{
nsAutoPtr<VObject> vObj(vCardService->Parse_MIME((const char *)data, datalen));
if (vObj)
{
PRInt32 len = 0;
nsAdoptingCString vCard(vCardService->WriteMemoryVObjects(0, &len, vObj, PR_FALSE));
nsCOMPtr <nsIAbCard> cardFromVCard;
rv = EscapedVCardToAbCard(vCard.get(), getter_AddRefs(cardFromVCard));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMWindowInternal> parentWindow = do_GetInterface(aContext);
NS_ENSURE_TRUE(parentWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMWindow> dialogWindow;
rv = parentWindow->OpenDialog(
NS_LITERAL_STRING("chrome://messenger/content/addressbook/abNewCardDialog.xul"),
EmptyString(),
NS_LITERAL_STRING("chrome,resizable=no,titlebar,modal,centerscreen"),
cardFromVCard, getter_AddRefs(dialogWindow));
}
}
return rv;
}
NS_IMETHODIMP nsAddressBook::EscapedVCardToAbCard(const char *aEscapedVCardStr, nsIAbCard **aCard)
{
NS_ENSURE_ARG_POINTER(aEscapedVCardStr);

View File

@ -46,6 +46,7 @@
#include "nsICmdLineHandler.h"
#include "nsIComponentManager.h"
#include "nsIContentHandler.h"
#include "nsIStreamLoader.h"
#include "rdf.h"
class nsILocalFile;
@ -82,7 +83,7 @@ const extern ExportAttributesTableStruct EXPORT_ATTRIBUTES_TABLE[EXPORT_ATTRIBUT
// are probably out there that can handle 4.x LDIF)
// else use the MOZ_AB_LDIF_PREFIX prefix, see nsIAddrDatabase.idl
class nsAddressBook : public nsIAddressBook, public nsICmdLineHandler, public nsIContentHandler
class nsAddressBook : public nsIAddressBook, public nsICmdLineHandler, public nsIContentHandler, public nsIStreamLoaderObserver
{
public:
@ -93,6 +94,7 @@ public:
NS_DECL_NSIADDRESSBOOK
NS_DECL_NSICMDLINEHANDLER
NS_DECL_NSICONTENTHANDLER
NS_DECL_NSISTREAMLOADEROBSERVER
CMDLINEHANDLER_REGISTERPROC_DECLS

View File

@ -36,21 +36,9 @@
* ***** END LICENSE BLOCK ***** */
#include "nsMsgVCardService.h"
#include "nsIDOMWindowInternal.h"
#include "nsVCardObj.h"
#include "nsISupportsPrimitives.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIAbCard.h"
#include "nsIAddressBook.h"
#include "nsAbBaseCID.h"
#include "prmem.h"
#include "plstr.h"
#define FOUR_K 4096
NS_IMPL_ISUPPORTS1(nsMsgVCardService, nsIMsgVCardService)
nsMsgVCardService::nsMsgVCardService()
@ -118,103 +106,3 @@ NS_IMETHODIMP_(char *) nsMsgVCardService::VObjectAnyValue(VObject * o)
PL_strcpy(retval, (char *) vObjectAnyValue(o));
return retval;
}
// helper class used to process a stream of vcard data
NS_IMPL_ISUPPORTS1(nsMsgVCardStreamListener, nsIStreamListener)
nsMsgVCardStreamListener::nsMsgVCardStreamListener()
{
m_dataBuffer = nsnull;
}
nsMsgVCardStreamListener::~nsMsgVCardStreamListener()
{
PR_Free(m_dataBuffer);
}
NS_IMETHODIMP
nsMsgVCardStreamListener::OnStartRequest(nsIRequest* request, nsISupports* aSupport)
{
if (!m_dataBuffer)
m_dataBuffer = (char*) PR_CALLOC(FOUR_K+1);
return NS_OK;
}
NS_IMETHODIMP
nsMsgVCardStreamListener::OnStopRequest(nsIRequest* request, nsISupports* aSupport,
nsresult status)
{
NS_ENSURE_ARG_POINTER(aSupport);
NS_ENSURE_SUCCESS(status, status); // don't process the vcard if we got a status error
nsresult rv = NS_OK;
// take our vCard string and open up an address book window based on it
nsCOMPtr<nsIMsgVCardService> vCardService = do_GetService(NS_MSGVCARDSERVICE_CONTRACTID);
if (vCardService)
{
VObject * vObj = vCardService->Parse_MIME(mVCardData.get(), mVCardData.Length());
if (vObj)
{
nsCAutoString vCard;
int len = 0;
vCard.Adopt(vCardService->WriteMemoryVObjects(0, &len, vObj, PR_FALSE));
delete vObj;
nsCOMPtr<nsIDOMWindowInternal> parentWindow = do_GetInterface(aSupport);
NS_ENSURE_TRUE(parentWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsIAddressBook> addressbook = do_CreateInstance(NS_ADDRESSBOOK_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsIAbCard> cardFromVCard;
rv = addressbook->EscapedVCardToAbCard(vCard.get(), getter_AddRefs(cardFromVCard));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
ifptr->SetData(cardFromVCard);
ifptr->SetDataIID(&NS_GET_IID(nsIAbCard));
nsCOMPtr<nsIDOMWindow> dialogWindow;
rv = parentWindow->OpenDialog(
NS_LITERAL_STRING("chrome://messenger/content/addressbook/abNewCardDialog.xul"),
EmptyString(),
NS_LITERAL_STRING("chrome,resizable=no,titlebar,modal,centerscreen"),
ifptr, getter_AddRefs(dialogWindow));
}
}
PR_FREEIF(m_dataBuffer);
return rv;
}
NS_IMETHODIMP nsMsgVCardStreamListener::OnDataAvailable(nsIRequest* request, nsISupports* aSupport,
nsIInputStream* inStream,
PRUint32 srcOffset,
PRUint32 count)
{
PRUint32 available, readCount, maxReadCount = FOUR_K;
PRUint32 writeCount;
nsresult rv = inStream->Available(&available);
while (NS_SUCCEEDED(rv) && available)
{
if (maxReadCount > available)
maxReadCount = available;
memset(m_dataBuffer, 0, FOUR_K+1);
rv = inStream->Read(m_dataBuffer, maxReadCount, &readCount);
if (NS_SUCCEEDED(rv))
{
// m_dataBuffer is null terminated so we can safely just append it to our vcard string
mVCardData += m_dataBuffer;
available -= readCount;
}
}
return rv;
}

View File

@ -40,7 +40,6 @@
#include "nsIMsgVCardService.h"
#include "nsISupports.h"
#include "nsIStreamListener.h"
class nsMsgVCardService : public nsIMsgVCardService
{
@ -52,23 +51,4 @@ public:
virtual ~nsMsgVCardService();
};
// a helper class for the vcard service which can process a vcard as an incoming
// stream and open it.
class nsMsgVCardStreamListener : public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
nsMsgVCardStreamListener();
virtual ~nsMsgVCardStreamListener();
protected:
char *m_dataBuffer;
nsCString mVCardData;
};
#endif /* nsMsgVCardService_h___ */

View File

@ -375,7 +375,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDAPProcessChangeLogData)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbDirectoryQueryProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbView)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgVCardService)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgVCardStreamListener)
////////////////////////////////////////////////////////////////////////////////
// bayesian spam filter factories
@ -856,8 +855,6 @@ static const nsModuleComponentInfo gComponents[] = {
NS_ABDIRECTORYQUERYPROXY_CONTRACTID, nsAbDirectoryQueryProxyConstructor},
{ "addressbook view", NS_ABVIEW_CID, NS_ABVIEW_CONTRACTID, nsAbViewConstructor},
{ "vcard helper service", NS_MSGVCARDSERVICE_CID, NS_MSGVCARDSERVICE_CONTRACTID, nsMsgVCardServiceConstructor },
{ "vcard stream listener", NS_MSGVCARDSTREAMLISTENER_CID, NS_MSGVCARDSTREAMLISTENER_CONTRACTID,
nsMsgVCardStreamListenerConstructor },
////////////////////////////////////////////////////////////////////////////////
// bayesian spam filter components