Bug 1139965 Add vcf to the list of supported addrbook export formats r=mkmelin AURORA_BASE_20150330
authorNeil Rashbrook <neil@parkwaycc.co.uk>
Mon, 30 Mar 2015 00:51:24 +0100
changeset 22238 0dbb2dcc87e5acfb6f0c3fd8fce7419b59ee7123
parent 22237 acac3827c58eefcd8c957cc4abeca57c7ae0539c
child 22239 a415a50bd40d46fc450dbc272d70bceb9800f24f
push idunknown
push userunknown
push dateunknown
reviewersmkmelin
bugs1139965
Bug 1139965 Add vcf to the list of supported addrbook export formats r=mkmelin
mailnews/addrbook/src/nsAbManager.cpp
mailnews/addrbook/src/nsAbManager.h
--- a/mailnews/addrbook/src/nsAbManager.cpp
+++ b/mailnews/addrbook/src/nsAbManager.cpp
@@ -511,24 +511,26 @@ NS_IMETHODIMP nsAbManager::MailListNameE
 #define CSV_DELIM ","
 #define CSV_DELIM_LEN 1
 #define TAB_DELIM "\t"
 #define TAB_DELIM_LEN 1
 
 #define CSV_FILE_EXTENSION ".csv"
 #define TAB_FILE_EXTENSION ".tab"
 #define TXT_FILE_EXTENSION ".txt"
+#define VCF_FILE_EXTENSION ".vcf"
 #define LDIF_FILE_EXTENSION ".ldi"
 #define LDIF_FILE_EXTENSION2 ".ldif"
 
 enum ADDRESSBOOK_EXPORT_FILE_TYPE
 {
  LDIF_EXPORT_TYPE =  0,
- CSV_EXPORT_TYPE = 1,
- TAB_EXPORT_TYPE = 2
+ CSV_EXPORT_TYPE =   1,
+ TAB_EXPORT_TYPE =   2,
+ VCF_EXPORT_TYPE =   3,
 };
 
 NS_IMETHODIMP nsAbManager::ExportAddressBook(nsIDOMWindow *aParentWin, nsIAbDirectory *aDirectory)
 {
   NS_ENSURE_ARG_POINTER(aParentWin);
 
   nsresult rv;
   nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1", &rv);
@@ -562,16 +564,22 @@ NS_IMETHODIMP nsAbManager::ExportAddress
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = bundle->GetStringFromName(MOZ_UTF16("TABFiles"), getter_Copies(filterString));
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = filePicker->AppendFilter(filterString, NS_LITERAL_STRING("*.tab; *.txt"));
   NS_ENSURE_SUCCESS(rv, rv);
 
+  rv = bundle->GetStringFromName(MOZ_UTF16("VCFFiles"), getter_Copies(filterString));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = filePicker->AppendFilter(filterString, NS_LITERAL_STRING("*.vcf"));
+  NS_ENSURE_SUCCESS(rv, rv);
+
   int16_t dialogResult;
   filePicker->Show(&dialogResult);
 
   if (dialogResult == nsIFilePicker::returnCancel)
     return rv;
 
   nsCOMPtr<nsIFile> localFile;
   rv = filePicker->GetFile(getter_AddRefs(localFile));
@@ -600,45 +608,56 @@ NS_IMETHODIMP nsAbManager::ExportAddress
   switch ( exportType )
   {
     default:
     case LDIF_EXPORT_TYPE: // ldif
       // If filename does not have the correct ext, add one.
       if ((MsgFind(fileName, LDIF_FILE_EXTENSION, true, fileName.Length() - strlen(LDIF_FILE_EXTENSION)) == -1) &&
           (MsgFind(fileName, LDIF_FILE_EXTENSION2, true, fileName.Length() - strlen(LDIF_FILE_EXTENSION2)) == -1)) {
 
-       // Add the extension and build a new localFile.
-       fileName.AppendLiteral(LDIF_FILE_EXTENSION2);
-       localFile->SetLeafName(fileName);
-    }
+        // Add the extension and build a new localFile.
+        fileName.AppendLiteral(LDIF_FILE_EXTENSION2);
+        localFile->SetLeafName(fileName);
+      }
       rv = ExportDirectoryToLDIF(aDirectory, localFile);
       break;
 
     case CSV_EXPORT_TYPE: // csv
       // If filename does not have the correct ext, add one.
       if (MsgFind(fileName, CSV_FILE_EXTENSION, true, fileName.Length() - strlen(CSV_FILE_EXTENSION)) == -1) {
 
-       // Add the extension and build a new localFile.
-       fileName.AppendLiteral(CSV_FILE_EXTENSION);
-       localFile->SetLeafName(fileName);
-    }
+        // Add the extension and build a new localFile.
+        fileName.AppendLiteral(CSV_FILE_EXTENSION);
+        localFile->SetLeafName(fileName);
+      }
       rv = ExportDirectoryToDelimitedText(aDirectory, CSV_DELIM, CSV_DELIM_LEN, localFile);
       break;
 
     case TAB_EXPORT_TYPE: // tab & text
       // If filename does not have the correct ext, add one.
       if ((MsgFind(fileName, TXT_FILE_EXTENSION, true, fileName.Length() - strlen(TXT_FILE_EXTENSION)) == -1) &&
           (MsgFind(fileName, TAB_FILE_EXTENSION, true, fileName.Length() - strlen(TAB_FILE_EXTENSION)) == -1)) {
 
-       // Add the extension and build a new localFile.
-       fileName.AppendLiteral(TXT_FILE_EXTENSION);
-       localFile->SetLeafName(fileName);
-  }
+        // Add the extension and build a new localFile.
+        fileName.AppendLiteral(TXT_FILE_EXTENSION);
+        localFile->SetLeafName(fileName);
+      }
       rv = ExportDirectoryToDelimitedText(aDirectory, TAB_DELIM, TAB_DELIM_LEN, localFile);
       break;
+
+    case VCF_EXPORT_TYPE: // vCard
+      // If filename does not have the correct ext, add one.
+      if (MsgFind(fileName, VCF_FILE_EXTENSION, true, fileName.Length() - strlen(VCF_FILE_EXTENSION)) == -1) {
+
+        // Add the extension and build a new localFile.
+        fileName.AppendLiteral(VCF_FILE_EXTENSION);
+        localFile->SetLeafName(fileName);
+      }
+      rv = ExportDirectoryToVCard(aDirectory, localFile);
+      break;
   };
 
   return rv;
 }
 
 nsresult
 nsAbManager::ExportDirectoryToDelimitedText(nsIAbDirectory *aDirectory, const char *aDelim, uint32_t aDelimLen, nsIFile *aLocalFile)
 {
@@ -817,16 +836,82 @@ nsAbManager::ExportDirectoryToDelimitedT
   NS_ENSURE_SUCCESS(rv,rv);
 
   rv = outputStream->Close();
   NS_ENSURE_SUCCESS(rv,rv);
   return NS_OK;
 }
 
 nsresult
+nsAbManager::ExportDirectoryToVCard(nsIAbDirectory *aDirectory, nsIFile *aLocalFile)
+{
+  nsCOMPtr <nsISimpleEnumerator> cardsEnumerator;
+  nsCOMPtr <nsIAbCard> card;
+
+  nsresult rv;
+
+  nsCOMPtr <nsIOutputStream> outputStream;
+  rv = MsgNewBufferedFileOutputStream(getter_AddRefs(outputStream),
+                                      aLocalFile,
+                                      PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
+                                      0664);
+
+  // the desired file may be read only
+  if (NS_FAILED(rv))
+    return rv;
+
+  uint32_t writeCount;
+  uint32_t length;
+
+  rv = aDirectory->GetChildCards(getter_AddRefs(cardsEnumerator));
+  if (NS_SUCCEEDED(rv) && cardsEnumerator) {
+    nsCOMPtr<nsISupports> item;
+    bool more;
+    while (NS_SUCCEEDED(cardsEnumerator->HasMoreElements(&more)) && more) {
+      rv = cardsEnumerator->GetNext(getter_AddRefs(item));
+      if (NS_SUCCEEDED(rv)) {
+        nsCOMPtr <nsIAbCard> card = do_QueryInterface(item, &rv);
+        NS_ENSURE_SUCCESS(rv,rv);
+
+        bool isMailList;
+        rv = card->GetIsMailList(&isMailList);
+        NS_ENSURE_SUCCESS(rv,rv);
+
+        if (isMailList) {
+          // we don't know how to export mailing lists to vcf
+          // use LDIF for that.
+        }
+        else {
+          nsCString escapedValue;
+          rv = card->TranslateTo(NS_LITERAL_CSTRING("vcard"), escapedValue);
+          NS_ENSURE_SUCCESS(rv,rv);
+
+          nsCString valueCStr;
+          MsgUnescapeString(escapedValue, 0, valueCStr);
+
+          length = valueCStr.Length();
+          rv = outputStream->Write(valueCStr.get(), length, &writeCount);
+          NS_ENSURE_SUCCESS(rv,rv);
+          if (length != writeCount)
+            return NS_ERROR_FAILURE;
+        }
+      }
+    }
+  }
+
+  rv = outputStream->Flush();
+  NS_ENSURE_SUCCESS(rv,rv);
+
+  rv = outputStream->Close();
+  NS_ENSURE_SUCCESS(rv,rv);
+  return NS_OK;
+}
+
+
+nsresult
 nsAbManager::ExportDirectoryToLDIF(nsIAbDirectory *aDirectory, nsIFile *aLocalFile)
 {
   nsCOMPtr <nsISimpleEnumerator> cardsEnumerator;
   nsCOMPtr <nsIAbCard> card;
 
   nsresult rv;
 
   nsCOMPtr <nsIOutputStream> outputStream;
--- a/mailnews/addrbook/src/nsAbManager.h
+++ b/mailnews/addrbook/src/nsAbManager.h
@@ -31,16 +31,17 @@ public:
   NS_DECL_NSICOMMANDLINEHANDLER
 
   nsresult Init();
 
 private:
 	virtual ~nsAbManager();
   nsresult GetRootDirectory(nsIAbDirectory **aResult);
   nsresult ExportDirectoryToDelimitedText(nsIAbDirectory *aDirectory, const char *aDelim, uint32_t aDelimLen, nsIFile *aLocalFile);
+  nsresult ExportDirectoryToVCard(nsIAbDirectory *aDirectory, nsIFile *aLocalFile);
   nsresult ExportDirectoryToLDIF(nsIAbDirectory *aDirectory, nsIFile *aLocalFile);
   nsresult AppendLDIFForMailList(nsIAbCard *aCard, nsIAbLDAPAttributeMap *aAttrMap, nsACString &aResult);
   nsresult AppendDNForCard(const char *aProperty, nsIAbCard *aCard, nsIAbLDAPAttributeMap *aAttrMap, nsACString &aResult);
   nsresult AppendBasicLDIFForCard(nsIAbCard *aCard, nsIAbLDAPAttributeMap *aAttrMap, nsACString &aResult);
   nsresult AppendProperty(const char *aProperty, const char16_t *aValue, nsACString &aResult);
   bool IsSafeLDIFString(const char16_t *aStr);
 
   struct abListener {