[haiku-commits] BRANCH jessicah-github.contacts [afaab8c] in src: apps/people-old apps/people kits/contact add-ons/translators/vcard add-ons/translators/person

  • From: jessicah-github.contacts <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 1 Jul 2014 13:01:38 +0200 (CEST)

added 4 changesets to branch 'refs/remotes/jessicah-github/contacts'
old head: 0000000000000000000000000000000000000000
new head: afaab8c55db06c1d075655993c4127867542dd6d
overview: https://github.com/jessicah/haiku/compare/afaab8c

----------------------------------------------------------------------------

75f2c88: Imported code from the original branch.

                                          [ Barrett <b.vitruvio@xxxxxxxxx> ]

79d1245: Removed unneeded files.

                                          [ Barrett <b.vitruvio@xxxxxxxxx> ]

c314ba7: Build system changes for contact kit in a packaged world.

                         [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ]

afaab8c: Also add VCard translator for a package managed world.

                         [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ]

----------------------------------------------------------------------------

76 files changed, 9863 insertions(+), 469 deletions(-)
build/jam/images/definitions/regular             |    2 +
headers/os/translation/TranslatorFormats.h       |    8 +-
headers/private/contact/AddressBook.h            |   38 +
headers/private/contact/Contact.h                |   86 ++
headers/private/contact/ContactDefs.h            |  133 ++
headers/private/contact/ContactField.h           |  302 +++++
headers/private/contact/ContactGroup.h           |   60 +
headers/private/contact/ContactRef.h             |   67 +
headers/private/contact/ContactRoster.h          |   42 +
headers/private/contact/RawContact.h             |   57 +
src/add-ons/translators/Jamfile                  |    2 +
src/add-ons/translators/person/Jamfile           |   26 +
src/add-ons/translators/person/PersonMain.cpp    |   17 +
.../translators/person/PersonTranslator.cpp      |  652 ++++++++++
.../translators/person/PersonTranslator.h        |   87 ++
.../translators/person/PersonTranslator.rdef     |   11 +
src/add-ons/translators/person/PersonView.cpp    |   78 ++
src/add-ons/translators/person/PersonView.h      |   18 +
src/add-ons/translators/vcard/Jamfile            |   29 +
src/add-ons/translators/vcard/VCardMain.cpp      |   17 +
src/add-ons/translators/vcard/VCardParser.cpp    |  212 ++++
src/add-ons/translators/vcard/VCardParser.h      |   58 +
src/add-ons/translators/vcard/VCardParserDefs.h  |  197 +++
.../translators/vcard/VCardTranslator.cpp        |  313 +++++
src/add-ons/translators/vcard/VCardTranslator.h  |   70 ++
.../translators/vcard/VCardTranslator.rdef       |   11 +
src/add-ons/translators/vcard/VCardView.cpp      |   65 +
src/add-ons/translators/vcard/VCardView.h        |   18 +
src/add-ons/translators/vcard/cardparser.c       |  737 +++++++++++
src/add-ons/translators/vcard/cardparser.h       |   67 +
.../AttributeTextControl.cpp                     |    0
.../AttributeTextControl.h                       |    0
src/apps/people-old/Jamfile                      |   24 +
src/apps/people-old/LICENSE                      |   31 +
src/apps/people-old/People.rdef                  |   53 +
src/apps/people-old/PeopleApp.cpp                |  362 ++++++
src/apps/people-old/PeopleApp.h                  |   67 +
src/apps/people-old/PersonIcons.h                |   40 +
src/apps/people-old/PersonView.cpp               |  449 +++++++
src/apps/people-old/PersonView.h                 |   76 ++
src/apps/people-old/PersonWindow.cpp             |  444 +++++++
src/apps/people-old/PersonWindow.h               |   71 ++
src/apps/people-old/PictureView.cpp              |  644 ++++++++++
src/apps/people-old/PictureView.h                |   65 +
src/apps/people-old/main.cpp                     |   19 +
src/apps/people/AddressView.cpp                  |  363 ++++++
src/apps/people/AddressView.h                    |   94 ++
src/apps/people/AddressWindow.cpp                |   99 ++
src/apps/people/AddressWindow.h                  |   38 +
src/apps/people/ContactFieldTextControl.cpp      |  122 ++
src/apps/people/ContactFieldTextControl.h        |   40 +
src/apps/people/GroupsWindow.cpp                 |   43 +
src/apps/people/GroupsWindow.h                   |   29 +
src/apps/people/Jamfile                          |    9 +-
src/apps/people/LICENSE                          |    0
src/apps/people/People.rdef                      |    6 +-
src/apps/people/PeopleApp.cpp                    |  190 +--
src/apps/people/PeopleApp.h                      |   18 +-
src/apps/people/PersonIcons.h                    |    0
src/apps/people/PersonView.cpp                   |  410 +++---
src/apps/people/PersonView.h                     |   78 +-
src/apps/people/PersonWindow.cpp                 |  289 +++--
src/apps/people/PersonWindow.h                   |   31 +-
src/apps/people/PictureView.cpp                  |   47 +-
src/apps/people/PictureView.h                    |    4 +
src/apps/people/main.cpp                         |    0
src/kits/Jamfile                                 |    1 +
src/kits/contact/AddressBook.cpp                 |  117 ++
src/kits/contact/Contact.cpp                     |  481 +++++++
src/kits/contact/ContactField.cpp                | 1178 ++++++++++++++++++
src/kits/contact/ContactGroup.cpp                |  197 +++
src/kits/contact/ContactPrivate.h                |  106 ++
src/kits/contact/ContactRef.cpp                  |  170 +++
src/kits/contact/ContactRoster.cpp               |   66 +
src/kits/contact/Jamfile                         |   25 +
src/kits/contact/RawContact.cpp                  |  256 ++++

############################################################################

Commit:      75f2c88f3c344dd9efe19d06db362fa387cf4fe1
Author:      Barrett <b.vitruvio@xxxxxxxxx>
Date:        Mon Jul 29 16:17:30 2013 UTC
Committer:   Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Sun May 25 01:23:44 2014 UTC

Imported code from the original branch.

----------------------------------------------------------------------------

diff --git a/headers/os/translation/TranslatorFormats.h 
b/headers/os/translation/TranslatorFormats.h
index 744c0c6..20d473a 100644
--- a/headers/os/translation/TranslatorFormats.h
+++ b/headers/os/translation/TranslatorFormats.h
@@ -61,7 +61,12 @@ enum {
        B_AU_FORMAT                             = 'AU  ',
 
        // Text formats
-       B_STYLED_TEXT_FORMAT    = 'STXT'
+       B_STYLED_TEXT_FORMAT    = 'STXT',
+
+       // Contact formats
+       B_CONTACT_FORMAT                = 'BCFM',
+       B_PERSON_FORMAT                 = 'BPFM',
+       B_VCARD_FORMAT                  = 'BVFM'
 };
 
 
diff --git a/headers/private/contact/AddressBook.h 
b/headers/private/contact/AddressBook.h
new file mode 100755
index 0000000..77b3294
--- /dev/null
+++ b/headers/private/contact/AddressBook.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef ADDRESS_BOOK_H
+#define ADDRESS_BOOK_H
+
+#include <ContactDefs.h>
+#include <Contact.h>
+#include <ContactGroup.h>
+#include <Path.h>
+#include <SupportDefs.h>
+
+class BAddressBook : public BContactGroup {
+public:
+                                                       BAddressBook();
+                                                       ~BAddressBook();
+                       status_t                InitCheck();
+
+                       status_t                AddContact(BContactRef contact);
+                       status_t                RemoveContact(BContactRef 
contact);
+
+                       BPath                   GetPath();
+
+//                     BContactList    ContactsByGroup(BContactGroup* group);
+//                     BContactList    ContactsByQuery(BContactQuery* query);
+
+//                     status_t                Commit();
+//                     status_t                Reload();
+
+       //static        BAddressBook* Default();
+private:
+                       status_t                _FindDir();
+                       status_t                fInitCheck;
+                       BPath                   fAddrBook;
+};
+
+#endif // ADDRESS_BOOK_H
diff --git a/headers/private/contact/Contact.h 
b/headers/private/contact/Contact.h
new file mode 100755
index 0000000..704e45d
--- /dev/null
+++ b/headers/private/contact/Contact.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2011 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef B_CONTACT_H
+#define B_CONTACT_H
+
+#include <Archivable.h>
+#include <ContactDefs.h>
+#include <ContactField.h>
+#include <ContactRef.h>
+#include <Message.h>
+#include <ObjectList.h>
+#include <RawContact.h>
+
+
+class BContact : public virtual BArchivable {
+public:
+                                                       BContact(BRawContact* 
contact = NULL);
+                                                       BContact(BContactRef& 
ref);
+                                                       BContact(BMessage* 
archive);
+                       virtual                 ~BContact();
+
+                       status_t                Archive(BMessage* archive, bool 
deep) const;
+       static BArchivable*             Instantiate(BMessage* data);
+
+                       status_t                InitCheck() const;
+
+                       int32                   ID();
+                       uint32                  GroupID();
+
+                       BContactRef     ContactRef();
+
+                       status_t                AddField(BContactField* field);
+                       status_t                
RemoveEquivalentFields(BContactField* field);
+                       status_t                RemoveField(BContactField* 
field);
+                       status_t                ReplaceField(BContactField* 
field);
+                       bool                    HasField(BContactField* field);
+
+                       BContactField*  FieldAt(int index);
+                       BContactField*  FieldByType(field_type type, int32 
index = 0);
+
+                       int32                   CountFields() const;
+                       int32                   CountFields(field_type code) 
const;
+
+                       const BContactFieldList& FieldList() const;
+
+                       bool                    IsEqual(BContact* contact);
+                       status_t                CopyFieldsFrom(BContact* 
contact);
+                       status_t                CreateDefaultFields();
+
+       // for the moment it supports only a BRawContact, in future
+       // the following methods will help to merge many BRawContacts
+       // into a BContact.
+       // delete the actual BRawContact objects
+                       status_t                Append(BRawContact* contact);
+                       const BRawContact&      RawContact() const;
+
+                       status_t                Commit();
+                       status_t                Reload();
+
+       static  BObjectList<field_type>& SupportedFields();
+       static  BObjectList<field_usage>& SupportedUsages();
+
+protected:
+       //              status_t                SetInternalID(uint32 id);
+       //              status_t                AppendGroup(uint32 id);
+       //              status_t                AppendGroup(BContactGroup 
group);
+
+private:
+                       status_t                _FlattenFields(BMessage* msg) 
const;
+                       status_t                _UnflattenFields(BMessage* msg);
+
+                       BRawContact*    fRawContact;
+                       status_t                fInitCheck;
+                       int32                   fID;
+                       uint32                  fGroupID;
+
+                       BContactFieldList fList;
+
+                       //friend class BContactRoster;
+};
+
+typedef BObjectList<BContact> BContactList;
+
+#endif // B_CONTACT_H
diff --git a/headers/private/contact/ContactDefs.h 
b/headers/private/contact/ContactDefs.h
new file mode 100755
index 0000000..49262ef
--- /dev/null
+++ b/headers/private/contact/ContactDefs.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2011 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef B_CONTACT_DEFS_H
+#define B_CONTACT_DEFS_H
+
+#include <Errors.h>
+
+
+enum DefaultDefs {
+       B_CONTACT_ANY = 'BCAN'
+};
+
+enum ContactGroupDefs {
+       B_CONTACT_GROUP_NONE = 1,
+       B_CONTACT_GROUP_DEFAULT = 'BCGD',
+       B_CONTACT_GROUP_ADDRESS_BOOK = 'BCSG'
+};
+
+// TODO update code
+// for missing fields
+enum ContactFieldType {
+       B_CONTACT_ADDRESS                = 'CFNA',
+       B_CONTACT_ASSISTANT              = 'BCAS',
+       B_CONTACT_BIRTHDAY               = 'BCBR',
+       B_CONTACT_CUSTOM                =  'CCUS',
+       B_CONTACT_DELIVERY_LABEL = 'BCDL',      
+       B_CONTACT_EMAIL                  = 'CFNE',
+       B_CONTACT_FORMATTED_NAME = 'CFFN',
+       B_CONTACT_GENDER                 = 'CFGN',
+       B_CONTACT_GEO                    = 'CFNG',
+       B_CONTACT_GROUP                  = 'CFNR',
+       B_CONTACT_IM                     = 'CFNI',
+       B_CONTACT_MANAGER                = 'BCMN',
+       B_CONTACT_NAME                   = 'CFNN',
+       B_CONTACT_NICKNAME               = 'CFNK',
+       B_CONTACT_NOTE                   = 'CFNO',
+       B_CONTACT_ORGANIZATION   = 'CFNJ',
+       B_CONTACT_PHONE                  = 'CFNP',
+       B_CONTACT_PHOTO                  = 'CFNH',
+       B_CONTACT_PROTOCOLS      = 'CFNL',
+       B_CONTACT_SIMPLE_GROUP   = 'CFSG',
+       B_CONTACT_SOUND                  = 'BCDS',
+       B_CONTACT_SPOUSE                 = 'BCSP',
+       B_CONTACT_TIME_ZONE      = 'CNTM',
+       B_CONTACT_TITLE                  = 'CNTL',
+       B_CONTACT_UID                    = 'CFND',
+       B_CONTACT_URL                    = 'CFNU',
+       B_CONTACT_REV                    = 'CFRV'
+};
+
+enum CommonFieldUsageTypes {
+       CONTACT_DATA_CUSTOM = 'CDTC',
+       CONTACT_DATA_OTHER      = 'CDOT',       
+       CONTACT_DATA_HOME       = 'CDHM',
+       CONTACT_DATA_WORK       = 'CDWK',
+       CONTACT_DATA_PREFERRED = 'CDPF'
+};
+
+enum SpecificFieldUsageTypes {
+       CONTACT_NAME_FAMILY = 'CNFM',
+       CONTACT_NAME_GIVEN      = 'CNGV',
+       CONTACT_NAME_MIDDLE     = 'CNMD',
+       CONTACT_NAME_SUFFIX     = 'CNSF',
+
+       CONTACT_NICKNAME_DEFAULT = 'CNDF',
+       CONTACT_NICKNAME_MAIDEN  = 'CNMN',
+       CONTACT_NICKNAME_SHORT_NAME      = 'CNSN',
+       CONTACT_NICKNAME_INITIALS        = 'CNIN',
+
+       CONTACT_EMAIL_INTERNET = 'CEIN',
+       CONTACT_EMAIL_MOBILE = 'CEMB',
+
+       CONTACT_PHONE_ASSISTANT = 'CPAS',
+       CONTACT_PHONE_CALLBACK = 'CPXK',
+       CONTACT_PHONE_CAR = 'CPCR',
+       CONTACT_PHONE_BBS = 'CPBS',
+       CONTACT_PHONE_FAX = 'CPFW',
+       CONTACT_PHONE_ISDN = 'CPIN',
+       CONTACT_PHONE_MMS = 'CPMS',
+       CONTACT_PHONE_MODEM = 'CPMD',
+       CONTACT_PHONE_MOBILE = 'CPMB',
+       CONTACT_PHONE_MSG = 'CPMG',
+       CONTACT_PHONE_PAGER = 'CPPG',
+       CONTACT_PHONE_RADIO = 'CPRA',
+       CONTACT_PHONE_TELEX = 'CPTE',
+       CONTACT_PHONE_TTY_TDD = 'CPTY',
+       CONTACT_PHONE_VIDEO = 'CPVD',
+       CONTACT_PHONE_VOICE = 'CPVC',
+
+       CONTACT_PHOTO_BITMAP = 'CPBT',
+       CONTACT_PHOTO_URL        = 'CPUL',
+/*     CONTACT_PHOTO_AVI = 'CPAV',
+       CONTACT_PHOTO_BMP = 'CPBM',
+       CONTACT_PHOTO_GIF = 'CPGF',
+       CONTACT_PHOTO_MPEG = 'CPMP',
+       CONTACT_PHOTO_MPEG2 = 'CPM2',
+       CONTACT_PHOTO_PS = 'CPPS',
+       CONTACT_PHOTO_PDF = 'CPPD',
+       CONTACT_PHOTO_QTIME = 'CPBT',
+       CONTACT_PHOTO_TIFF = 'CPTF',
+       CONTACT_PHOTO_JPEG = 'CPJP',
+       CONTACT_PHOTO_CGM = 'CPCG',
+       CONTACT_PHOTO_WMF = 'CPWM',
+       CONTACT_PHOTO_MET = 'CPME',
+       CONTACT_PHOTO_PBM = 'CPPB',
+       CONTACT_PHOTO_DIB = 'CPDI',
+       CONTACT_PHOTO_PICT = 'CPPI',*/
+
+       CONTACT_ADDRESS_DOM = 'CADM',
+       CONTACT_ADDRESS_INTL = 'CAIN',
+       CONTACT_ADDRESS_POSTAL = 'CAPO',
+       CONTACT_ADDRESS_PARCEL = 'CAPA',
+
+       CONTACT_SOUND_WAVE = 'CSWV',
+       CONTACT_SOUND_PCM = 'CSPC',
+       CONTACT_SOUND_AIFF = 'CSAI',
+       CONTACT_SOUND_MP3 = 'CSM3',
+       CONTACT_SOUND_OGG = 'CSOG',
+
+       CONTACT_IM_AIM = 'CIMA',
+       CONTACT_IM_ICQ = 'CIMI',
+       CONTACT_IM_MSN = 'CIMM',
+       CONTACT_IM_JABBER = 'CIMJ',
+       CONTACT_IM_YAHOO = 'CIMY',
+       CONTACT_IM_TWITTER = 'CIMT',
+       CONTACT_IM_SKYPE = 'CIMS',
+       CONTACT_IM_GADUGADU = 'CIMG',
+       CONTACT_IM_GROUPWISE = 'CIMW'
+};
+
+#endif // B_CONTACT_DEFS_H
diff --git a/headers/private/contact/ContactField.h 
b/headers/private/contact/ContactField.h
new file mode 100755
index 0000000..94731c2
--- /dev/null
+++ b/headers/private/contact/ContactField.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2011 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef _CONTACTFIELD_H_
+#define _CONTACTFIELD_H_
+
+#include <Bitmap.h>
+#include <ContactDefs.h>
+#include <Flattenable.h>
+#include <Message.h>
+#include <ObjectList.h>
+#include <String.h>
+
+#define CONTACT_FIELD_IDENT "contactfield"
+
+typedef type_code field_type;
+typedef type_code field_usage;
+
+enum {
+       B_CONTACT_FIELD_TYPE = 'CNFT'
+};
+
+class BContactFieldVisitor;
+
+
+class BContactField : public virtual BFlattenable {
+public:
+                                                       
BContactField(field_type type,
+                                                               bool autoLabel 
= false);
+       virtual                                 ~BContactField();
+
+       virtual void                    SetValue(const BString& value) = 0;
+       virtual const BString&  Value() const = 0;
+
+                       field_usage             GetUsage(int32 i) const;
+                       void                    AddUsage(field_usage usage);
+                       int32                   CountUsages() const;
+
+       virtual void                    Accept(BContactFieldVisitor* visitor) = 
0;
+       virtual bool                    IsEqual(BContactField* field);
+                       type_code               FieldType() const;
+                       
+       virtual bool                    IsHidden() const;
+
+                       // those provide a human-friendly
+                       // description of the field
+                       const BString&  Label() const;
+                       void                    SetLabel(const BString& label);
+
+       static  const char*             SimpleLabel(field_type code);
+       static  const char*             ExtendedLabel(BContactField* field);
+
+       virtual bool                    IsFixedSize() const;
+       virtual type_code               TypeCode() const;
+       virtual bool                    AllowsTypeCode(type_code code) const;
+       virtual ssize_t                 FlattenedSize() const;
+
+                       status_t                Flatten(BPositionIO* flatData) 
const;
+       virtual status_t                Flatten(void* buffer, ssize_t size) 
const;
+       virtual status_t                Unflatten(type_code code, const void* 
buffer,
+                                                               ssize_t size);
+                       status_t                Unflatten(type_code code, 
BPositionIO* flatData);
+
+       static  BContactField*  Duplicate(BContactField* from);
+       static  BContactField*  UnflattenChildClass(const void* data,
+                                                               ssize_t size);
+       static  BContactField*  InstantiateChildClass(type_code type);
+       virtual status_t                CopyDataFrom(BContactField* field);
+
+//     static  BObjectList<field_usage>& SupportedUsages(field_type code);
+private:
+//     virtual void*                   GetUntranslatedData();
+//     virtual void                    SetUntranslatedData(void* data);
+
+protected:
+                       ssize_t                 _AddStringToBuffer(BPositionIO* 
buffer,
+                                                               const BString& 
str) const;
+                       BString                 
_ReadStringFromBuffer(BPositionIO* buffer,
+                                                               ssize_t len = 
-1);
+       static void                             _UpdateLabel(field_usage usage, 
BString& str);
+
+                       BString                 fLabel;
+                       field_type              fType;
+                       //int32                 fUsage;
+                       BObjectList<field_usage> fUsages;
+
+                       friend class    EqualityVisitorBase;
+                       friend class    CopyVisitorBase;
+};
+
+
+/*** Contact Fields implementations ***/
+
+class BStringContactField : public BContactField {
+public:
+                                                       
BStringContactField(field_type type,
+                                                               const BString& 
str);
+
+                                                       
BStringContactField(field_type type,
+                                                               const char* str 
= "");
+
+       virtual                                 ~BStringContactField();
+
+       virtual void                    Accept(BContactFieldVisitor* v);
+
+       virtual bool                    IsEqual(BContactField* field);
+       virtual void                    SetValue(const BString& value);
+       virtual const BString&  Value() const;
+
+       virtual ssize_t                 FlattenedSize() const;
+       virtual status_t                Flatten(void* buffer, ssize_t size) 
const;
+       virtual status_t                Unflatten(type_code code, const void* 
buffer,
+                                                               ssize_t size);
+
+       virtual status_t                CopyDataFrom(BContactField* field);
+private:
+                       struct                  EqualityVisitor;
+                       struct                  CopyVisitor;
+
+                       BString                 fValue;
+};
+
+
+// TODO move code into a BAddress object
+class BAddressContactField : public BContactField {
+public:
+                                                       BAddressContactField(
+                                                               field_type type 
= B_CONTACT_ADDRESS,
+                                                               BString address 
= "");
+
+       virtual                                 ~BAddressContactField();
+
+                       void                    Accept(BContactFieldVisitor* v);
+                       bool                    IsEqual(BContactField* field);
+
+                       bool                    IsDeliveryLabel() const;
+                       //void                  SetDeliveryLabel(bool isLabel);
+
+       // these accept/return a formatted address (see vcard)
+       virtual void                    SetValue(const BString& value) ;
+       virtual const BString&  Value() const;
+
+                       const BString&  Street() const;
+                       const BString&  PostalBox() const;
+                       const BString&  Neighborhood() const;
+                       const BString&  City() const;
+                       const BString&  Region() const;
+                       const BString&  PostalCode() const;
+                       const BString&  Country() const;
+
+                       void                    SetStreet(const BString& 
street);
+                       void                    SetPostalBox(const BString& 
postBox);
+                       void                    SetNeighborhood(const BString& 
neighbor);
+                       void                    SetCity(const BString& city);
+                       void                    SetRegion(const BString& 
region);
+                       void                    SetPostalCode(const BString& 
postalCode);
+                       void                    SetCountry(const BString& 
country);
+
+       virtual ssize_t                 FlattenedSize() const;
+       virtual status_t                Flatten(void* buffer, ssize_t size) 
const;
+       virtual status_t                Unflatten(field_type code, const void* 
buffer,
+                                                               ssize_t size);
+
+       virtual status_t                CopyDataFrom(BContactField* field);
+private:
+                       bool                    _SplitValue(const BString& str);
+                       void                    _PopValue(BString& str, 
BString& value);
+
+                       struct                  EqualityVisitor;
+                       struct                  CopyVisitor;
+
+                       BString                 fStreet;
+                       BString                 fPostalBox;
+                       BString                 fNeighbor;
+                       BString                 fCity;
+                       BString                 fRegion;
+                       BString                 fPostalCode;
+                       BString                 fCountry;
+
+       mutable BString                 fValue;
+                       const char*             fDivider;
+};
+
+
+class BPhotoContactField : public virtual BContactField {
+public:
+                                                       
BPhotoContactField(BBitmap* bitmap = NULL);
+       virtual                                 ~BPhotoContactField();
+
+       virtual void                    Accept(BContactFieldVisitor* v);
+       virtual bool                    IsEqual(BContactField* field);
+
+                       BBitmap*                Photo() const;
+                       void                    SetPhoto(BBitmap* photo);
+
+       // dunno if the value is useful
+       virtual void                    SetValue(const BString& value) ;
+       virtual const BString&  Value() const;
+
+       virtual ssize_t                 FlattenedSize() const;
+       virtual status_t                Flatten(void* buffer, ssize_t size) 
const;
+       virtual status_t                Unflatten(type_code code, const void* 
buffer,
+                                                               ssize_t size);
+
+       virtual status_t                CopyDataFrom(BContactField* field);
+
+                       uint32                  PictureType() const;
+                       void                    SetPictureType(uint32 type);
+                       const BString&  PictureMIME() const;
+                       void                    SetPictureMIME(const BString& 
mime);
+private:
+                       void                    _CleanUp();
+
+                       struct                  EqualityVisitor;
+                       struct                  CopyVisitor;
+
+                       BBitmap*                fBitmap;
+//                     entry_ref*              fEntry;
+                       BString                 fUrl;
+
+                       int32                   fPhotoType;
+                       uint32                  fPictureType;
+                       BString                 fPictureMIME;
+};
+
+/*
+// This is a field used to provide raw unknown data
+class BRawDataContactField : public virtual BContactField {
+public:
+                                                       
BPhotoContactField(BBitmap* bitmap = NULL);
+       virtual                                 ~BPhotoContactField();
+
+       virtual void                    Accept(BContactFieldVisitor* v);
+       virtual bool                    IsEqual(BContactField* field);
+
+                       const BString&  Identifier() const;
+
+       virtual void                    SetValue(const BString& value);
+       virtual const BString&  Value() const;
+
+       virtual ssize_t                 FlattenedSize() const;
+       virtual status_t                Flatten(void* buffer, ssize_t size) 
const;
+       virtual status_t                Unflatten(type_code code, const void* 
buffer,
+                                                               ssize_t size);
+
+       virtual status_t                CopyDataFrom(BContactField* field);
+private:
+                       void                    _CleanUp();
+
+                       struct                  EqualityVisitor;
+                       struct                  CopyVisitor;
+
+                       BString                 fValue;
+};
+
+
+This will be a special type of field
+that will provide a method to define
+custom contact fields presumably
+using a BMessage or any other type of
+internal representation, as preferred.
+
+This is not intended to be used directly.
+
+class BCustomContactField : public virtual BContactField {
+public:
+                                                       
BCustomContactField(BMessage* message,
+                                                               const char* 
type);
+       virtual                                 ~BCustomContactField();
+
+                       void                    Accept(BContactFieldVisitor* v);
+                       bool                    IsEqual(BContactField* field);
+
+                       BMessage*               AsTemplate();
+
+       virtual void                    SetValue(const BString& value) ;
+       virtual const BString&  Value() const;
+
+       virtual ssize_t                 FlattenedSize() const;
+       virtual status_t                Flatten(void* buffer, ssize_t size) 
const;
+       virtual status_t                Unflatten(type_code code, const void* 
buffer,
+                                                               ssize_t size);
+
+       virtual BString&                CustomLabel() = 0;
+
+private:
+                       struct                  EqualityVisitor;
+};
+
+*/
+
+class BContactFieldVisitor {
+public:
+       virtual void                    Visit(BStringContactField* field) = 0;
+       virtual void                    Visit(BAddressContactField* field) = 0;
+       virtual void                    Visit(BPhotoContactField* field) = 0;
+};
+
+typedef BObjectList<BContactField> BContactFieldList;
+
+#endif // _CONTACTFIELD_H_
diff --git a/headers/private/contact/ContactGroup.h 
b/headers/private/contact/ContactGroup.h
new file mode 100755
index 0000000..172cfbf
--- /dev/null
+++ b/headers/private/contact/ContactGroup.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011-2012 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef _CONTACT_GROUP_H
+#define _CONTACT_GROUP_H
+
+#include <ContactDefs.h>
+#include <ContactRef.h>
+#include <Flattenable.h>
+#include <Message.h>
+#include <SupportDefs.h>
+
+enum {
+       B_CONTACT_GROUP_TYPE = 'CNGT'
+};
+
+
+class BContactGroup : public BFlattenable {
+public:
+                                                       BContactGroup(
+                                                               uint32 groupID 
= B_CONTACT_GROUP_NONE,
+                                                               bool custom = 
false);
+
+                                                       ~BContactGroup();
+
+       virtual bool                    IsFixedSize() const;
+       virtual type_code               TypeCode() const;
+       virtual bool                    AllowsTypeCode(type_code code) const;
+       virtual ssize_t                 FlattenedSize() const;
+
+                       status_t                Flatten(BPositionIO* flatData) 
const;
+       virtual status_t                Flatten(void* buffer, ssize_t size) 
const;
+       virtual status_t                Unflatten(type_code code, const void* 
buffer,
+                                                               ssize_t size);
+                       status_t                Unflatten(type_code code, 
BPositionIO* flatData);
+
+                       status_t                InitCheck() const;
+
+       virtual status_t                AddContact(BContactRef contact);
+       virtual status_t                RemoveContact(BContactRef contact);
+       virtual int32                   CountContacts() const;
+       virtual BContactRef             ContactAt(int32 index) const;
+
+                       const BContactRefList AllContacts() const;
+
+                       /*BContactList* ContactsByQuery(BContactQuery* query);
+                       const BContactRefList* ContactsByField(ContactFieldType 
type,
+                               const char* value = NULL) const;*/
+protected:
+                       BContactRefList fList;
+private:
+                       status_t                fInitCheck;
+                       uint32                  fGroupID;
+                       bool                    fCustom;
+};
+
+typedef BObjectList<BContactGroup> BContactGroupList;
+
+#endif // _CONTACT_GROUP_H
diff --git a/headers/private/contact/ContactRef.h 
b/headers/private/contact/ContactRef.h
new file mode 100755
index 0000000..b637628
--- /dev/null
+++ b/headers/private/contact/ContactRef.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 - 2012 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef _CONTACT_REF_H
+#define _CONTACT_REF_H
+
+#include <ContactDefs.h>
+#include <DataIO.h>
+#include <Flattenable.h>
+#include <ObjectList.h>
+#include <String.h>
+
+enum {
+       B_CONTACT_REF_TYPE = 'CRft'
+};
+
+class BContactRef : public virtual BFlattenable {
+public:
+                                               BContactRef(int32 id = -1,
+                                                       uint32 groupID = 
B_CONTACT_GROUP_NONE,
+                                                       bool autoFill = false);
+
+                                               BContactRef(const BContactRef& 
ref);
+
+                                               ~BContactRef();
+
+       virtual bool            IsFixedSize() const;
+       virtual type_code       TypeCode() const;
+       virtual bool            AllowsTypeCode(type_code code) const;
+       virtual ssize_t         FlattenedSize() const;
+
+                       status_t        Flatten(BPositionIO* flatData) const;
+       virtual status_t        Flatten(void* buffer, ssize_t size) const;
+       virtual status_t        Unflatten(type_code code, const void* buffer,
+                                                       ssize_t size);
+                       status_t        Unflatten(type_code code, BPositionIO* 
flatData);
+
+                       void            SetName(const char* name);
+                       void            SetNickname(const char* nickname);
+                       void            SetEmail(const char* email);
+
+                       const char* GetName();
+                       const char* GetNickname();
+                       const char* GetEmail();
+                       int32           GetID();
+                       uint32          GetGroupID();
+
+                       bool            IsEqual(const BContactRef& ref) const;
+private:
+                       ssize_t         _AddStringToBuffer(BPositionIO* buffer,
+                                                       const char* str) const;
+                       const char* _ReadStringFromBuffer(BPositionIO* buffer,
+                                                       ssize_t len = -1);
+
+                       BString         fName;
+                       BString         fNickname;
+                       BString         fEmail;
+                       int32           fContactID;
+                       uint32          fGroupID;
+};
+
+// TODO compositing instead of inheriting
+
+typedef BObjectList<BContactRef> BContactRefList;
+
+#endif
diff --git a/headers/private/contact/ContactRoster.h 
b/headers/private/contact/ContactRoster.h
new file mode 100755
index 0000000..9d35e7e
--- /dev/null
+++ b/headers/private/contact/ContactRoster.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef CONTACT_ROSTER_H
+#define CONTACT_ROSTER_H
+
+#include <AddressBook.h>
+#include <Contact.h>
+#include <ContactGroup.h>
+
+// Basically, i think this will supply support functions
+// and support to register BContacts over the system.
+
+// The AddressBook will be a special group, that have their objects
+// automatically published in /boot/home/peole. I don't think any other
+// group should be allowed here (you can add a contact to multiple groups 
anyway)
+
+class BContactRoster {
+public:
+                                               BContactRoster();
+
+       status_t                        RegisterContact(BContactRef& contact);
+       status_t                        UnregisterContact(BContactRef& contact);
+
+       // if a contact isn't registered the following will return NULL.
+       BContact*                       InstantiateContact(BContactRef& ref);
+       BContactGroup*          InstantiateGroup(uint32 id);
+
+       BContactGroupList*      GroupsForRef(BContactRef& ref);
+
+       BContactGroupList*      RegisteredGroups();
+
+//     BContactRefList*        ContactsByQuery(BContactQuery* query);
+
+       BAddressBook*           AddressBook();
+
+private:
+
+};
+
+#endif // CONTACT_ROSTER_H
diff --git a/headers/private/contact/RawContact.h 
b/headers/private/contact/RawContact.h
new file mode 100755
index 0000000..87702c3
--- /dev/null
+++ b/headers/private/contact/RawContact.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011-2012 Haiku Inc.
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef B_RAW_CONTACT_H
+#define B_RAW_CONTACT_H
+
+#include <Archivable.h>
+#include <ContactDefs.h>
+#include <Message.h>
+#include <TranslatorFormats.h>
+#include <TranslatorRoster.h>
+
+class BRawContact : public virtual BArchivable {
+public:
+                                       // Initialize the RawContact from
+                                       // a BMessage if it's valid.
+                                       BRawContact(BMessage* data);
+
+                                       BRawContact(uint32 finalFormat = 
B_CONTACT_FORMAT,
+                                               BPositionIO* destination = 
NULL);
+
+                                       // TODO add a entry_ref constructor
+
+                                       ~BRawContact();
+
+       status_t                Archive(BMessage* data, bool deep) const;
+
+       static BArchivable*     Instantiate(BMessage* data);
+
+       status_t                InitCheck() const;
+
+       status_t                Commit(BMessage* data);
+       status_t                Read(BMessage* data);
+       int32                   FinalFormat() const;
+
+       BPositionIO*    Destination() const;
+       status_t                SetDestination(BPositionIO* destination,
+                                               bool autoDelete = true);
+private:
+       void                    _Init();
+       void                    _InitTranslator();
+       bool                    _CheckDestination(BPositionIO* destination);
+       status_t                _FindFormat();
+
+       BPositionIO*    fDest;
+
+       status_t                fInitCheck;
+       // translation stuff
+       uint32                  fFormat;
+       // the id of the suitable translator
+       translator_id   fTranslatorID;
+
+       BTranslatorRoster* fRoster;
+};
+
+#endif // B_RAW_CONTACT_H
diff --git a/src/add-ons/translators/Jamfile b/src/add-ons/translators/Jamfile
index 782bae1..54dddde 100644
--- a/src/add-ons/translators/Jamfile
+++ b/src/add-ons/translators/Jamfile
@@ -9,6 +9,7 @@ SubInclude HAIKU_TOP src add-ons translators ico ;
 SubInclude HAIKU_TOP src add-ons translators jpeg ;
 SubInclude HAIKU_TOP src add-ons translators jpeg2000 ;
 SubInclude HAIKU_TOP src add-ons translators pcx ;
+SubInclude HAIKU_TOP src add-ons translators person ;
 SubInclude HAIKU_TOP src add-ons translators png ;
 SubInclude HAIKU_TOP src add-ons translators ppm ;
 SubInclude HAIKU_TOP src add-ons translators raw ;
@@ -18,6 +19,7 @@ SubInclude HAIKU_TOP src add-ons translators shared ;
 SubInclude HAIKU_TOP src add-ons translators stxt ;
 SubInclude HAIKU_TOP src add-ons translators tga ;
 SubInclude HAIKU_TOP src add-ons translators tiff ;
+SubInclude HAIKU_TOP src add-ons translators vcard ;
 SubInclude HAIKU_TOP src add-ons translators webp ;
 SubInclude HAIKU_TOP src add-ons translators wonderbrush ;
 SubInclude HAIKU_TOP src add-ons translators icns ;
diff --git a/src/add-ons/translators/person/Jamfile 
b/src/add-ons/translators/person/Jamfile
new file mode 100755
index 0000000..56a7d4e
--- /dev/null
+++ b/src/add-ons/translators/person/Jamfile
@@ -0,0 +1,19 @@
+SubDir HAIKU_TOP src add-ons translators person ;
+
+SetSubDirSupportedPlatformsBeOSCompatible ;
+
+UsePrivateHeaders contact ;
+UsePrivateHeaders shared ;
+
+SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ;
+
+AddResources PersonTranslator : PersonTranslator.rdef ;
+
+Translator PersonTranslator :
+       PersonMain.cpp
+       PersonTranslator.cpp
+       PersonView.cpp
+       : be translation libcontact.so libtranslatorsutils.a libshared.a
+       $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS)
+       : true
+;
diff --git a/src/add-ons/translators/person/PersonMain.cpp 
b/src/add-ons/translators/person/PersonMain.cpp
new file mode 100755
index 0000000..d0a85a7
--- /dev/null
+++ b/src/add-ons/translators/person/PersonMain.cpp
@@ -0,0 +1,17 @@
+#include <Application.h>
+
+#include "PersonTranslator.h"
+
+int main()
+{
+       BApplication app("application/x-vnd.Haiku-PersonTranslator");
+       status_t result;
+       result = LaunchTranslatorWindow(new PersonTranslator,
+               "VCard Settings", BRect(0, 0, 225, 175));
+       if (result == B_OK) {
+               app.Run();
+               return 0;
+       } else
+               return 1;
+}
+
diff --git a/src/add-ons/translators/person/PersonTranslator.cpp 
b/src/add-ons/translators/person/PersonTranslator.cpp
new file mode 100755
index 0000000..c6d15c7
--- /dev/null
+++ b/src/add-ons/translators/person/PersonTranslator.cpp
@@ -0,0 +1,652 @@
+#include "PersonTranslator.h"
+
+#include <shared/AutoDeleter.h>
+#include <BitmapStream.h>
+#include <ContactDefs.h>
+#include <ContactField.h>
+#include <fs_attr.h>
+#include <MimeType.h>
+#include <Node.h>
+#include <NodeInfo.h>
+#include <File.h>
+#include <ObjectList.h>
+#include <Volume.h>
+#include <VolumeRoster.h>
+
+#include <new>
+#include <stdio.h>
+#include <syslog.h>
+
+#include "PersonView.h"
+
+const char* kTranslatorName = "Person Contacts Files";
+const char* kTranslatorInfo = "Translator for Person files";
+
+// TODO URGENT clean node attributes before to save
+
+#define PEOPLE_MIME_TYPE "application/x-person"
+#define CONTACT_MIME_TYPE "application/x-hcontact"
+
+static const translation_format sInputFormats[] = {
+               {
+               B_CONTACT_FORMAT,
+               B_TRANSLATOR_CONTACT,
+               IN_QUALITY,
+               IN_CAPABILITY,
+               CONTACT_MIME_TYPE,
+               "Haiku binary contact"
+       },
+       {
+               B_PERSON_FORMAT,
+               B_TRANSLATOR_CONTACT,
+               IN_QUALITY,
+               IN_CAPABILITY,
+               PEOPLE_MIME_TYPE,
+               "Person Contact file"
+       }
+};
+
+// The output formats that this translator supports.
+static const translation_format sOutputFormats[] = {
+               {
+               B_CONTACT_FORMAT,
+               B_TRANSLATOR_CONTACT,
+               OUT_QUALITY,
+               OUT_CAPABILITY,
+               CONTACT_MIME_TYPE,
+               "Haiku binary contact"
+       },
+       {
+               B_PERSON_FORMAT,
+               B_TRANSLATOR_CONTACT,
+               OUT_QUALITY,
+               OUT_CAPABILITY,
+               PEOPLE_MIME_TYPE,
+               "Person Contact file"
+       }
+};
+
+// Default settings for the Translator
+static const TranSetting sDefaultSettings[] = {
+};
+
+const uint32 kNumInputFormats = sizeof(sInputFormats)
+       / sizeof(translation_format);
+
+const uint32 kNumOutputFormats = sizeof(sOutputFormats)
+       / sizeof(translation_format);
+
+const uint32 kNumDefaultSettings = sizeof(sDefaultSettings)
+       / sizeof(TranSetting);
+
+/*
+struct Attribute {
+       const char*     attribute;
+       int32           width;
+       const char*     name;
+};
+
+// TODO: Add flags in attribute info message to find these.
+//static const char* kNameAttribute = "META:name";
+//static const char* kCategoryAttribute = "META:group";
+
+struct Attribute sDefaultAttributes[] = {
+       { B_PEOPLE_NAME, B_TRANSLATE("Contact name") },
+       { B_PEOPLE_NICKNAME, B_TRANSLATE("Nickname") },
+       { B_PEOPLE_COMPANY, B_TRANSLATE("Company") },
+       { B_PEOPLE_ADDRESS, B_TRANSLATE("Address") },
+       { B_PEOPLE_CITY, B_TRANSLATE("City") },
+       { B_PEOPLE_STATE, B_TRANSLATE("State") },
+       { B_PEOPLE_ZIP, B_TRANSLATE("Zip") },
+       { B_PEOPLE_COUNTRY, B_TRANSLATE("Country") },
+       { B_PEOPLE_HPHONE, B_TRANSLATE("Home phone") },
+       { B_PEOPLE_WPHONE, B_TRANSLATE("Work phone") },
+       { B_PEOPLE_FAX, B_TRANSLATE("Fax") },
+       { B_PEOPLE_EMAIL, B_TRANSLATE("E-mail") },
+       { B_PEOPLE_URL, B_TRANSLATE("URL") },
+       { B_PEOPLE_GROUP, B_TRANSLATE("Group") },
+       { NULL, 0, NULL }
+};
+*/
+
+struct PersonVisitor : public BContactFieldVisitor {
+public:
+                                       PersonVisitor(BFile* destination)
+                                       :
+                                       fDest(destination)
+                                       {
+                                       }
+       virtual                 ~PersonVisitor()
+                                       {
+                                       }
+
+       virtual void    Visit(BStringContactField* field)
+       {
+               BString str;
+               switch (field->FieldType()) {
+               case B_CONTACT_FORMATTED_NAME:
+                       str << B_PEOPLE_NAME;
+               break;
+               case B_CONTACT_NICKNAME:
+                       str << B_PEOPLE_NICKNAME;
+               break;
+// the Person format is not supporting notes
+// maybe it's the case to extend the attributes
+//                     case B_CONTACT_NOTE:
+//             break;
+               case B_CONTACT_ORGANIZATION:
+                       str << B_PEOPLE_COMPANY;
+               break;
+               case B_CONTACT_EMAIL:
+                       str << B_PEOPLE_EMAIL;
+               break;
+               case B_CONTACT_URL:
+                       str << B_PEOPLE_URL;
+               break;
+               case B_CONTACT_PHONE:
+                       str = _TranslatePhone(field);
+               break;
+
+//             case B_CONTACT_GROUP:
+                                       
+//             break;
+
+               }               
+               _WriteAttribute(str.String(), field->Value()); 
+       }
+
+       virtual void    Visit(BAddressContactField* field)
+       {
+               _WriteAttribute(B_PEOPLE_ADDRESS, field->Street());
+               _WriteAttribute(B_PEOPLE_CITY, field->City());
+               _WriteAttribute(B_PEOPLE_STATE, field->Region());
+               _WriteAttribute(B_PEOPLE_ZIP, field->PostalCode());
+               _WriteAttribute(B_PEOPLE_COUNTRY, field->Country());
+       }
+
+       virtual void    Visit(BPhotoContactField* field)
+       {
+               BBitmap* picture = field->Photo();
+               if (picture) {
+                       fDest->Seek(SEEK_SET, 0);
+                       BBitmapStream stream(picture);
+                       // Detach *our* bitmap from stream to avoid its deletion
+                       // at stream object destruction
+                       stream.DetachBitmap(&picture);
+
+                       BTranslatorRoster* roster = 
BTranslatorRoster::Default();
+                       roster->Translate(&stream, NULL, NULL, fDest,
+                               field->PictureType(), B_TRANSLATOR_BITMAP,
+                               NULL);
+               }
+       }
+
+       void    WriteType()
+       {
+               BNodeInfo(fDest).SetType(PEOPLE_MIME_TYPE);
+       }
+
+private:
+
+       BString _TranslatePhone(BStringContactField* field)
+       {
+               // TODO use a map here
+               if (field == NULL)
+                       return "";
+
+               BString str;
+
+               if (field->CountUsages() < 1)
+                       return str.Append(B_PEOPLE_HPHONE);
+
+               for (int i = 0; i < field->CountUsages(); i++) {
+                       field_usage usage = field->GetUsage(i);
+                       switch (usage) {
+                               case CONTACT_DATA_OTHER:
+                               case CONTACT_DATA_HOME:
+                               case CONTACT_PHONE_MOBILE:
+                                       str.Append(B_PEOPLE_HPHONE);
+                               break;
+                               case CONTACT_DATA_WORK:
+                                       str.Append(B_PEOPLE_WPHONE);
+                               break;
+                               case CONTACT_PHONE_FAX:
+                                       str.SetTo(B_PEOPLE_FAX);
+                               break;
+
+                               case CONTACT_PHONE_VOICE:
+                               break;
+
+                               default:
+                                       str.SetTo(B_PEOPLE_HPHONE);
+                       }
+               }
+               return str;
+       }
+
+                       void    _WriteAttribute(const char* attrName, const 
BString& value)
+       {
+               if (strlen(attrName) < 1 || value.Length() < 0)
+                       return;
+               fDest->WriteAttr(attrName, B_STRING_TYPE, 0,
+               value.String(), value.Length() + 1);
+       }
+
+       BFile* fDest;
+};
+
+
+// required by the BaseTranslator class
+BTranslator *
+make_nth_translator(int32 n, image_id you, uint32 flags, ...)
+{
+       if (!n)
+               return new (std::nothrow) PersonTranslator();
+
+       return NULL;
+}
+
+
+PersonTranslator::PersonTranslator()
+       :
+       BaseTranslator(kTranslatorName, kTranslatorInfo, 
PERSON_TRANSLATOR_VERSION,
+               sInputFormats, kNumInputFormats, sOutputFormats, 
kNumOutputFormats,
+               "PersonTranslatorSettings", sDefaultSettings, 
kNumDefaultSettings,
+               B_TRANSLATOR_CONTACT, B_PERSON_FORMAT)
+{
+}
+
+
+PersonTranslator::~PersonTranslator()
+{
+}
+
+
+status_t
+PersonTranslator::Identify(BPositionIO* inSource,
+       const translation_format* inFormat, BMessage* ioExtension,
+       translator_info* outInfo, uint32 outType)
+{
+       if (!outType)
+               outType = B_CONTACT_FORMAT;
+
+       if (outType != B_CONTACT_FORMAT && outType != B_PERSON_FORMAT)
+               return B_NO_TRANSLATOR;
+
+       BMessage msg;
+       if (outType == B_PERSON_FORMAT && msg.Unflatten(inSource) == B_OK) {
+               outInfo->type = B_CONTACT_FORMAT;
+               outInfo->group = B_TRANSLATOR_CONTACT;
+               outInfo->quality = IN_QUALITY;
+               outInfo->capability = IN_CAPABILITY;
+               snprintf(outInfo->name, sizeof(outInfo->name), kTranslatorName);
+               strcpy(outInfo->MIME, CONTACT_MIME_TYPE);
+               return B_OK;
+       } else if (outType == B_CONTACT_FORMAT)
+               return _IdentifyPerson(inSource, outInfo);
+
+       return B_NO_TRANSLATOR;
+}
+
+
+status_t
+PersonTranslator::Translate(BPositionIO* inSource, const translator_info* info,
+       BMessage* ioExtension, uint32 outType, BPositionIO* outDestination)
+{
+       if (!outType)
+               outType = B_CONTACT_FORMAT;
+
+       if (outType != B_CONTACT_FORMAT && outType != B_PERSON_FORMAT)
+               return B_NO_TRANSLATOR;
+
+       // TODO add no translation
+       BMessage msg;
+       if (outType == B_PERSON_FORMAT && msg.Unflatten(inSource) == B_OK) {
+               if (outDestination == NULL)
+                       return false;
+
+               BFile* file = _PositionToFile(outDestination);
+               if (file != NULL)
+                       return TranslateContact(&msg, ioExtension, file);
+               else
+                       return B_ERROR;
+       } else if (outType == B_CONTACT_FORMAT)
+               return TranslatePerson(inSource, ioExtension, outDestination);
+
+       return B_NO_TRANSLATOR;
+}
+
+
+status_t
+PersonTranslator::TranslateContact(BMessage* inSource, 
+               BMessage* ioExtension, BFile* outDestination)
+{
+       int32 count;
+       type_code code = B_CONTACT_FIELD_TYPE;
+       PersonVisitor visitor(outDestination);
+
+       visitor.WriteType();
+
+       status_t ret = inSource->GetInfo(CONTACT_FIELD_IDENT, &code, &count);
+       if (ret != B_OK)
+               return ret;
+
+       for (int i = 0; i < count; i++) {
+               const void* data;
+               ssize_t size;
+
+               ret = inSource->FindData(CONTACT_FIELD_IDENT, code,
+                       i, &data, &size);
+
+               BContactField* field = BContactField::UnflattenChildClass(data, 
size);
+               if (field == NULL)
+                       return B_ERROR;
+
+               field->Accept(&visitor);
+
+               delete field;
+       }
+       return B_OK;
+}
+
+
+status_t
+PersonTranslator::TranslatePerson(BPositionIO* inSource, 
+               BMessage* ioExtension, BPositionIO* outDestination)
+{
+       BFile* file = _PositionToFile(inSource);
+       if (file != NULL) {
+               ObjectDeleter<BAddressContactField> deleter;
+               BAddressContactField* addressField
+                       = new BAddressContactField();
+               deleter.SetTo(addressField);
+
+               BMessage msg;
+               char buf[B_ATTR_NAME_LENGTH];
+               while (file->GetNextAttrName(buf) == B_OK) {
+                       char* value;
+                       attr_info info;
+                       if (file->GetAttrInfo(buf, &info) != B_OK)
+                               continue;
+
+                       value = (char*)calloc(info.size, 1);
+                       if (value == NULL)
+                               return B_NO_MEMORY;
+
+                       file->ReadAttr(buf, 0, 0, value, info.size);
+                       
+                       BContactField* field = NULL;
+                       if (strcmp(buf, B_PEOPLE_NAME) == 0) {
+                               field = new BStringContactField(
+                                       B_CONTACT_FORMATTED_NAME, value);
+                       } else if (strcmp(buf, B_PEOPLE_NICKNAME) == 0) {
+                               field = new 
BStringContactField(B_CONTACT_NICKNAME, value);
+                       } else if (strcmp(buf, B_PEOPLE_COMPANY) == 0) {
+                               field = new 
BStringContactField(B_CONTACT_ORGANIZATION, value);
+                       } else if (strcmp(buf, B_PEOPLE_ADDRESS) == 0) {
+                               addressField->SetStreet(value);
+                       } else if (strcmp(buf, B_PEOPLE_CITY) == 0) {
+                               addressField->SetCity(value);
+                       } else if (strcmp(buf, B_PEOPLE_STATE) == 0) {
+                               addressField->SetRegion(value);
+                       } else if (strcmp(buf, B_PEOPLE_ZIP) == 0) {
+                               addressField->SetPostalCode(value);
+                       } else if (strcmp(buf, B_PEOPLE_COUNTRY) == 0) {
+                               addressField->SetCountry(value);
+                       } else if (strcmp(buf, B_PEOPLE_HPHONE) == 0) {
+                               field = new 
BStringContactField(B_CONTACT_PHONE, value);
+                               field->AddUsage(CONTACT_DATA_HOME);
+                       } else if (strcmp(buf, B_PEOPLE_WPHONE) == 0) {
+                               field = new 
BStringContactField(B_CONTACT_PHONE, value);
+                               field->AddUsage(CONTACT_DATA_WORK);
+                       } else if (strcmp(buf, B_PEOPLE_FAX) == 0) {
+                               field = new 
BStringContactField(B_CONTACT_PHONE, value);;
+                               field->AddUsage(CONTACT_PHONE_FAX);
+                       } else if (strcmp(buf, B_PEOPLE_EMAIL) == 0) {
+                               field = new 
BStringContactField(B_CONTACT_EMAIL, value);
+                       } else if (strcmp(buf, B_PEOPLE_URL) == 0) {
+                               field = new BStringContactField(B_CONTACT_URL, 
value);
+                       } else if (strcmp(buf, B_PEOPLE_GROUP) == 0) {
+                               //
+                       }
+
+                       if (field != NULL)
+                               _AddField(field, &msg);
+
+                       delete field;
+                       free(value);
+               }
+
+               if (addressField->Value().Length() > 0)
+                       _AddField(addressField, &msg);
+               else
+                       delete addressField;
+
+               _AddPicture(file, &msg);
+
+               msg.PrintToStream();
+               outDestination->Seek(0, SEEK_SET);
+               msg.Flatten(outDestination);
+               return B_OK;
+       }
+       return B_NO_TRANSLATOR;
+}
+
+
+status_t
+PersonTranslator::_IdentifyPerson(BPositionIO* inSource,
+       translator_info* outInfo)
+{
+       BFile* file = _PositionToFile(inSource);
+       if (file != NULL) {
+               char type[B_MIME_TYPE_LENGTH];
+               BNodeInfo info(file);
+               if (info.InitCheck() == B_OK) {
+                       info.GetType(type);
+                       if (strcmp(type, PEOPLE_MIME_TYPE) == 0) {
+                               outInfo->type = B_PERSON_FORMAT;
+                               outInfo->group = B_TRANSLATOR_CONTACT;
+                               outInfo->quality = IN_QUALITY;
+                               outInfo->capability = IN_CAPABILITY;
+                               snprintf(outInfo->name,
+                                       sizeof(outInfo->name), kTranslatorName);
+
+                               strcpy(outInfo->MIME, PEOPLE_MIME_TYPE);
+                               return B_OK;
+                       }
+               }
+               return B_OK;
+       }
+       return B_NO_TRANSLATOR;
+}
+
+
+BView*
+PersonTranslator::NewConfigView(TranslatorSettings *settings)
+{
+       return new PersonView(BRect(0, 0, 225, 175), 
+               "PersonTranslator Settings", B_FOLLOW_ALL,
+               B_WILL_DRAW, settings);
+}
+
+
+BFile*
+PersonTranslator::_PositionToFile(BPositionIO* destination)
+{
+       BFile* file = dynamic_cast<BFile*>(destination);
+       if (file != NULL && file->InitCheck() == B_OK)
+               return file;
+       else
+               return NULL;
+}
+
+
+status_t
+PersonTranslator::_AddField(BContactField* field, BMessage* msg)
+{
+       if (field != NULL) {
+               ssize_t size = field->FlattenedSize();
+
+               void* buffer = new char [size];
+               if (buffer == NULL)
+                       return B_NO_MEMORY;
+               MemoryDeleter deleter(buffer);
+
+               status_t ret = field->Flatten(buffer, size);
+               if (ret != B_OK)
+                       return ret;
+
+               ret = msg->AddData(CONTACT_FIELD_IDENT, field->TypeCode(),
+                       buffer, size, false);
+               if (ret != B_OK)
+                       return ret;
+
+               return B_OK;
+       }
+       return B_ERROR;
+}
+
+
+status_t
+PersonTranslator::_AddPicture(BFile* file, BMessage* msg)
+{
+       off_t fileSize;
+       status_t status = file->GetSize(&fileSize);
+               if (status != B_OK)
+                       return B_ERROR;
+
+               if (fileSize < 1)
+                       return B_ERROR;
+
+       translator_info info;
+       memset(&info, 0, sizeof(translator_info));
+       BMessage ioExtension;
+
+       BTranslatorRoster* roster = BTranslatorRoster::Default();
+
+       if (roster == NULL)
+               return B_NO_MEMORY;
+
+       status = roster->Identify(file, &ioExtension, &info, 0, NULL,
+               B_TRANSLATOR_BITMAP);
+
+       BBitmapStream stream;
+
+       if (status == B_OK) {
+               status = roster->Translate(file, &info, &ioExtension, &stream,
+                       B_TRANSLATOR_BITMAP);
+       }
+       if (status != B_OK)
+               return status;
+
+       BBitmap* picture = NULL;
+       if (stream.DetachBitmap(&picture) != B_OK
+               || picture == NULL)
+               return B_ERROR;
+
+       BPhotoContactField* field = new BPhotoContactField(picture);
+
+       // Remember image format so we could store using the same
+       //field->SetMIMEType(info.MIME);
+       field->SetPictureType(info.type);
+
+       return _AddField(field, msg);
+}
+
+
+// Read attributes from person mime type. If it does not exist,
+// or if it contains no attribute definitions, install a "clean"
+// person mime type from the hard-coded default attributes.
+/*
+status_t
+PersonTranslator::_InitAttr()
+{
+       bool valid = false;
+       BMimeType mime(PEOPLE_MIMETYPE);
+       if (mime.IsInstalled()) {
+               BMessage info;
+               if (mime.GetAttrInfo(&info) == B_NO_ERROR) {
+                       int32 index = 0;
+                       while (true) {
+                               int32 type;
+                               if (info.FindInt32("attr:type", index, &type) 
!= B_OK)
+                                       break;
+                               bool editable;
+                               if (info.FindBool("attr:editable", index, 
&editable) != B_OK)
+                                       break;
+
+                               // TODO: Support other types besides string 
attributes.
+                               if (type != B_STRING_TYPE || !editable)
+                                       break;
+
+                               Attribute* attribute = new Attribute();
+                               ObjectDeleter<Attribute> deleter(attribute);
+                               if (info.FindString("attr:public_name", index,
+                                               &attribute->name) != B_OK) {
+                                       break;
+                               }
+                               if (info.FindString("attr:name", index,
+                                               &attribute->attribute) != B_OK) 
{
+                                       break;
+                               }
+
+                               if (!fAttributes.AddItem(attribute))
+                                       break;
+
+                               deleter.Detach();
+                               index++;
+                       }
+               }
+               if (fAttributes.CountItems() == 0) {
+                       valid = false;
+                       mime.Delete();
+               } else
+                       valid = true;
+       }
+       if (!valid) {
+               mime.Install();
+               mime.SetShortDescription(B_TRANSLATE_WITH_CONTEXT("Person",
+                       "Short mimetype description"));
+               mime.SetLongDescription(B_TRANSLATE_WITH_CONTEXT(
+                       "Contact information for a person.",
+                       "Long mimetype description"));
+               mime.SetIcon(kPersonIcon, sizeof(kPersonIcon));
+               mime.SetPreferredApp(APP_SIG);
+
+               // add default person fields to meta-mime type
+               BMessage fields;
+               for (int32 i = 0; sDefaultAttributes[i].attribute; i++) {
+                       fields.AddString("attr:public_name", 
sDefaultAttributes[i].name);
+                       fields.AddString("attr:name", 
sDefaultAttributes[i].attribute);
+                       fields.AddInt32("attr:type", B_STRING_TYPE);
+                       fields.AddBool("attr:viewable", true);
+                       fields.AddBool("attr:editable", true);
+                       fields.AddInt32("attr:width", 
sDefaultAttributes[i].width);
+                       fields.AddInt32("attr:alignment", B_ALIGN_LEFT);
+                       fields.AddBool("attr:extra", false);
+
+                       // Add the default attribute to the attribute list, too.
+                       Attribute* attribute = new Attribute();
+                       attribute->name = sDefaultAttributes[i].name;
+                       attribute->attribute = sDefaultAttributes[i].attribute;
+                       if (!fAttributes.AddItem(attribute))
+                               delete attribute;
+               }
+
+               mime.SetAttrInfo(&fields);
+       }
+
+       // create indices on all volumes for the found attributes.
+
+       int32 count = fAttributes.CountItems();
+       BVolumeRoster volumeRoster;
+       BVolume volume;
+       while (volumeRoster.GetNextVolume(&volume) == B_OK) {
+               for (int32 i = 0; i < count; i++) {
+                       Attribute* attribute = fAttributes.ItemAt(i);
+                       fs_create_index(volume.Device(), attribute->attribute,
+                               B_STRING_TYPE, 0);
+               }
+       }
+}
+*/
diff --git a/src/add-ons/translators/person/PersonTranslator.h 
b/src/add-ons/translators/person/PersonTranslator.h
new file mode 100755
index 0000000..fcc908b
--- /dev/null
+++ b/src/add-ons/translators/person/PersonTranslator.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 Dario Casalinuovo <your@email.address>
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef _PERSON_TRANSLATOR_H
+#define _PERSON_TRANSLATOR_H
+
+#include <ContactDefs.h>
+#include <Translator.h>
+#include <TranslatorFormats.h>
+#include <TranslationDefs.h>
+
+#include "BaseTranslator.h"
+#include "PersonView.h"
+#include "TranslatorSettings.h"
+#include "TranslatorWindow.h"
+
+#define PERSON_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(0,1,0)
+#define IN_QUALITY 1
+#define IN_CAPABILITY 1
+#define OUT_QUALITY 1
+#define OUT_CAPABILITY 1
+
+#define B_PEOPLE_NAME "META:name"
+#define B_PEOPLE_NICKNAME "META:nickname"
+#define B_PEOPLE_COMPANY "META:company"
+#define B_PEOPLE_ADDRESS "META:address"
+#define B_PEOPLE_CITY "META:city"
+#define B_PEOPLE_STATE "META:state"
+#define B_PEOPLE_ZIP "META:zip"
+#define B_PEOPLE_COUNTRY "META:country"
+#define B_PEOPLE_HPHONE "META:hphone"
+#define B_PEOPLE_WPHONE "META:wphone"
+#define B_PEOPLE_FAX "META:fax"
+#define B_PEOPLE_EMAIL "META:email"
+#define B_PEOPLE_URL "META:url"
+#define B_PEOPLE_GROUP "META:group"
+
+class BFile;
+class BContactField;
+
+class PersonTranslator : public BaseTranslator {
+public:
+       PersonTranslator();
+       
+       virtual status_t Identify(BPositionIO* inSource,
+               const translation_format* inFormat, BMessage* ioExtension,
+               translator_info* outInfo, uint32 outType);
+               // determines whether or not this translator can convert the
+               // data in inSource to the type outType
+
+       virtual status_t Translate(BPositionIO* inSource,
+               const translator_info* inInfo, BMessage* ioExtension,
+               uint32 outType, BPositionIO* outDestination);
+               // this function is the whole point of the Translation Kit,
+               // it translates the data in inSource to outDestination
+               // using the format outType
+
+                       status_t TranslateContact(BMessage* inSource, 
+                               BMessage* ioExtension, BFile* outDestination);
+
+                       status_t TranslatePerson(BPositionIO* inSource, 
+                               BMessage* ioExtension, BPositionIO* 
outDestination);
+
+       virtual BView*  NewConfigView(TranslatorSettings* settings);
+
+protected:
+       virtual                 ~PersonTranslator();
+               // this is protected because the object is deleted by the
+               // Release() function instead of being deleted directly by
+               // the user
+               
+private:
+                       status_t _IdentifyPerson(BPositionIO* inSource,
+                                               translator_info* outInfo);
+
+                       BFile*   _PositionToFile(BPositionIO* destination);
+                       status_t _AddField(BContactField* field, BMessage* msg);
+
+                       status_t _InitializeAttributes(BFile* file);
+                       status_t _CheckPerson(BPositionIO* people);
+                       status_t _AddPicture(BFile* file, BMessage* msg);
+
+               //      status_t _InitAttr();
+};
+
+#endif // #ifndef _Person_TRANSLATOR_H
diff --git a/src/add-ons/translators/person/PersonTranslator.rdef 
b/src/add-ons/translators/person/PersonTranslator.rdef
new file mode 100755
index 0000000..b425cfc
--- /dev/null
+++ b/src/add-ons/translators/person/PersonTranslator.rdef
@@ -0,0 +1,11 @@
+resource app_signature "application/x-vnd.Haiku-PersonTranslator";
+
+resource app_version {
+       major  = 1,
+       middle = 0,
+       minor  = 0,
+       variety = 0,
+       internal = 0,
+       short_info = "1.0.0",
+       long_info = "Haiku Person format Translator."
+};
diff --git a/src/add-ons/translators/person/PersonView.cpp 
b/src/add-ons/translators/person/PersonView.cpp
new file mode 100755
index 0000000..2199664
--- /dev/null
+++ b/src/add-ons/translators/person/PersonView.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2002-2011, Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT license.
+ *
+ * Authors:
+ *             Michael Wilber
+ *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ */
+
+/*! A view with information about the PersonTranslator. */
+
+
+#include "PersonView.h"
+#include "PersonTranslator.h"
+
+#include <StringView.h>
+
+#include <stdio.h>
+
+
+PersonView::PersonView(const BRect &frame, const char *name, uint32 resizeMode,
+               uint32 flags, TranslatorSettings *settings)
+       :
+       BView(frame, name, resizeMode, flags)
+{
+       // TODO use layouts
+       fSettings = settings;
+       SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+
+       font_height fontHeight;
+       be_bold_font->GetHeight(&fontHeight);
+       float height = fontHeight.descent + fontHeight.ascent + 
fontHeight.leading;
+
+       BRect rect(10, 10, 200, 10 + height);
+       BStringView *stringView = new BStringView(rect, "title",
+               "Person files translator");
+
+       stringView->SetFont(be_bold_font);
+       stringView->ResizeToPreferred();
+       AddChild(stringView);
+
+       float maxWidth = stringView->Bounds().Width();
+
+       rect.OffsetBy(0, height + 10);
+       char version[256];
+
+       snprintf(version, sizeof(version), "Version %d.%d.%d, %s",
+               int(PERSON_TRANSLATOR_VERSION),
+               int(PERSON_TRANSLATOR_VERSION),
+               int(PERSON_TRANSLATOR_VERSION),
+               __DATE__);
+
+       stringView = new BStringView(rect, "version", version);
+       stringView->ResizeToPreferred();
+       AddChild(stringView);
+
+       if (stringView->Bounds().Width() > maxWidth)
+               maxWidth = stringView->Bounds().Width();
+
+       GetFontHeight(&fontHeight);
+       height = fontHeight.descent + fontHeight.ascent + fontHeight.leading;
+
+       rect.OffsetBy(0, height + 5);
+       stringView = new BStringView(rect, "Copyright",
+               B_UTF8_COPYRIGHT "2011 Haiku Inc.");
+
+       stringView->ResizeToPreferred();
+       AddChild(stringView);
+
+       if (maxWidth + 20 > Bounds().Width())
+               ResizeTo(maxWidth + 20, Bounds().Height());
+}
+
+
+PersonView::~PersonView()
+{
+       fSettings->Release();
+}
diff --git a/src/add-ons/translators/person/PersonView.h 
b/src/add-ons/translators/person/PersonView.h
new file mode 100755
index 0000000..2c5d0b1
--- /dev/null
+++ b/src/add-ons/translators/person/PersonView.h
@@ -0,0 +1,18 @@
+#ifndef PERSON_VIEW_H
+#define PERSON_VIEW_H
+
+#include <View.h>
+
+#include "TranslatorSettings.h"
+
+class PersonView : public BView {
+       public:
+               PersonView(const BRect& frame, const char* name, uint32 
resizeMode,
+                       uint32 flags, TranslatorSettings* settings);
+               virtual ~PersonView();
+
+       private:
+               TranslatorSettings *fSettings;
+};
+
+#endif // #ifndef Person_VIEW_H
diff --git a/src/add-ons/translators/vcard/Jamfile 
b/src/add-ons/translators/vcard/Jamfile
new file mode 100755
index 0000000..ce27dc5
--- /dev/null
+++ b/src/add-ons/translators/vcard/Jamfile
@@ -0,0 +1,21 @@
+SubDir HAIKU_TOP src add-ons translators vcard ;
+
+SetSubDirSupportedPlatformsBeOSCompatible ;
+
+UsePrivateHeaders contact ;
+UsePrivateHeaders shared ;
+
+SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ;
+
+AddResources VCardTranslator : VCardTranslator.rdef ;
+
+Translator VCardTranslator :
+       VCardMain.cpp
+       VCardParser.cpp
+       VCardTranslator.cpp
+       VCardView.cpp
+       cardparser.c
+       : be translation libcontact.so libtranslatorsutils.a libshared.a
+       $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS)
+       : true
+;
diff --git a/src/add-ons/translators/vcard/VCardMain.cpp 
b/src/add-ons/translators/vcard/VCardMain.cpp
new file mode 100755
index 0000000..21508f0
--- /dev/null
+++ b/src/add-ons/translators/vcard/VCardMain.cpp
@@ -0,0 +1,17 @@
+#include <Application.h>
+
+#include "VCardTranslator.h"
+
+int main()
+{
+       BApplication app("application/x-vnd.Haiku-VCardTranslator");
+       status_t result;
+       result = LaunchTranslatorWindow(new VCardTranslator,
+               "VCard Settings", BRect(0, 0, 225, 175));
+       if (result == B_OK) {
+               app.Run();
+               return 0;
+       } else
+               return 1;
+}
+
diff --git a/src/add-ons/translators/vcard/VCardParser.cpp 
b/src/add-ons/translators/vcard/VCardParser.cpp
new file mode 100755
index 0000000..e1f49ba
--- /dev/null
+++ b/src/add-ons/translators/vcard/VCardParser.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2011-2012 Dario Casalinuovo
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#include "VCardParser.h"
+
+#include <stdio.h>
+
+
+// c++ bindings to the c API
+void HandleProp(void* userData,
+       const CARD_Char* propName, const CARD_Char** params)
+{
+       VCardParser* owner = (VCardParser*) userData;
+       owner->PropHandler(propName, params);
+}
+
+
+void
+HandleData(void* userData, const CARD_Char* data, int len)
+{
+       VCardParser* owner = (VCardParser*) userData;
+       owner->DataHandler(data, len);
+}
+
+
+VCardParser::VCardParser(BPositionIO* from, bool onlyCheck)
+       :
+       fFrom(from),
+       fOnlyCheck(onlyCheck),
+       fCheck(false),
+       fBegin(false),
+       fEnd(false),
+       fLatestParams(true),
+       fList(true),
+       fFieldsMap(),
+       fUsagesMap()
+{
+       // intialize the parser
+       fParser = CARD_ParserCreate(NULL);
+       CARD_SetUserData(fParser, this);
+       CARD_SetPropHandler(fParser, HandleProp);
+       CARD_SetDataHandler(fParser, HandleData);
+
+       // fill the map with the values to translate from VCard to BContact
+       for (int i = 0; gFieldsMap[i].key != NULL; i++)
+               fFieldsMap.Put(HashString(gFieldsMap[i].key), 
gFieldsMap[i].type);
+
+       for (int i = 0; gUsagesMap[i].key != NULL; i++)
+               fUsagesMap.Put(HashString(gUsagesMap[i].key), 
gUsagesMap[i].usage);
+}
+
+
+VCardParser::~VCardParser()
+{
+       // free the object
+       CARD_ParserFree(fParser);
+}
+
+
+status_t
+VCardParser::Parse()
+{
+       if (fFrom == NULL)
+               return B_ERROR;
+
+       char buf[512];
+       ssize_t read;
+       read = fFrom->Read(buf, sizeof(buf));
+
+       while (read > 0) {
+               int err = CARD_Parse(fParser, buf, read, false);
+               if (err == 0)
+                       return B_ERROR;
+               read = fFrom->Read(buf, sizeof(buf));
+       }
+       // end of the parse
+       CARD_Parse(fParser, NULL, 0, true);
+       return B_OK;
+}
+
+
+bool
+VCardParser::HasBegin()
+{
+       return fBegin && fCheck;
+}
+
+
+bool
+VCardParser::HasEnd()
+{
+       return fEnd && fCheck;
+}
+
+
+int32
+VCardParser::CountProperties()
+{
+       return fList.CountItems();
+}
+
+
+BContactField*
+VCardParser::PropertyAt(int32 i)
+{
+       return fList.ItemAt(i);
+}
+
+       
+BContactFieldList*
+VCardParser::Properties()
+{
+       return &fList;
+}
+
+
+void
+VCardParser::PropHandler(const CARD_Char* propName, const CARD_Char** params)
+{
+       if (!fBegin && strcasecmp(propName, "BEGIN") == 0) {
+               fBegin = true;
+        return;
+       }
+
+       // if we don't have a BEGIN:VCARD field
+       // we just don't accept the following data.
+    if (!fBegin)
+        return;
+
+       if (strcasecmp(propName, "END") == 0) {
+               fEnd = true;
+               return;
+       }
+       
+       if (!fCheck)
+               return;
+
+       if (fOnlyCheck)
+               return;
+
+       printf("-----%s\n", propName);
+
+       fLatestProp.SetTo(propName);
+
+       fLatestParams.MakeEmpty();
+       for (int i = 0; params[i] != NULL; i++) {       
+               fLatestParams.AddItem(new BString(params[i]));
+               if (params[i+1] == NULL)
+                       i++;
+       }
+}
+
+
+void
+VCardParser::DataHandler(const CARD_Char* data, int len)
+{
+       BString str(data, len);
+
+       if (fBegin && !fCheck) {
+               if (len > 0) {
+                       if (str.ICompare("VCARD") == 0)
+                               fCheck = true;
+                       return;
+               }
+       } else if (fEnd) {
+               if (len > 0) {
+                       if (str.ICompare("VCARD") == 0)
+                               fCheck = true;
+                       else
+                               fCheck = false;
+               }
+               return;
+       }
+
+       if (fOnlyCheck)
+               return;
+
+       if (len == 0)
+               return;
+
+       str = "";
+       for (int i = 0; i < len; i++) {
+               CARD_Char c = data[i];
+               if (c == '\r' || c == '\n')
+                       continue;
+               else if (c >= ' ' && c <= '~')
+                       str.Append((char)c, 1);
+       }
+
+       field_type type = fFieldsMap.Get(HashString(fLatestProp));
+       BContactField* field = BContactField::InstantiateChildClass(type);
+
+       if (field != NULL) {
+               _TranslateUsage(field);
+               fList.AddItem(field);
+               field->SetValue(str);
+               //printf("data %s\n", field->Value().String());
+       }
+}
+
+
+void
+VCardParser::_TranslateUsage(BContactField* field) {
+       int count = fLatestParams.CountItems();
+       for (int i = 0; i < count; i++) {
+               BString param = fLatestParams.ItemAt(i)->String();
+               field_usage usage = fUsagesMap.Get(HashString(param));
+               field->AddUsage(usage);
+               //printf("----Param : %s\n", fLatestParams.ItemAt(i)->String());
+       }
+}
diff --git a/src/add-ons/translators/vcard/VCardParser.h 
b/src/add-ons/translators/vcard/VCardParser.h
new file mode 100755
index 0000000..501c231
--- /dev/null
+++ b/src/add-ons/translators/vcard/VCardParser.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011-2012 Dario Casalinuovo
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef _VCARD_PARSER_H
+#define _VCARD_PARSER_H
+
+#include <ContactDefs.h>
+#include <ContactField.h>
+
+#include <ObjectList.h>
+#include <SupportDefs.h>
+
+#include "cardparser.h"
+#include "VCardParserDefs.h"
+
+typedef BObjectList<BString> StringList;
+
+class VCardParser {
+public:
+                                       VCardParser(BPositionIO* from, bool 
check = false);
+       virtual                 ~VCardParser();
+
+       status_t                Parse();
+
+       bool                    HasBegin();
+       bool                    HasEnd();
+
+       const char*             Version();
+
+       void                    PropHandler(const CARD_Char* propName,
+                                               const CARD_Char** params);
+       void                    DataHandler(const CARD_Char* data, int len);
+
+       int32                   CountProperties();
+       BContactField*  PropertyAt(int32 i);
+       // rename Fields
+       BContactFieldList* Properties();
+private:
+       void                    _TranslateUsage(BContactField* field);
+
+       CARD_Parser     fParser;
+       BPositionIO*    fFrom;
+
+       bool                    fOnlyCheck;
+       bool                    fCheck;
+       bool                    fBegin;
+       bool                    fEnd;
+       BString                 fLatestProp;
+       StringList              fLatestParams;
+
+       BContactFieldList fList;
+
+       InFieldsMap             fFieldsMap;
+       InUsagesMap             fUsagesMap;
+};
+
+#endif // _H
diff --git a/src/add-ons/translators/vcard/VCardParserDefs.h 
b/src/add-ons/translators/vcard/VCardParserDefs.h
new file mode 100755
index 0000000..0f96d41
--- /dev/null
+++ b/src/add-ons/translators/vcard/VCardParserDefs.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2010-2012 Casalinuovo Dario
+ * All rights reserved. Distributed under the terms of the MIT license.
+ */
+#ifndef _VCARD_PARSER_DEFS_H
+#define _VCARD_PARSER_DEFS_H
+
+#include <ContactDefs.h>
+#include <ContactField.h>
+#include <HashMap.h>
+#include <HashString.h>
+
+using BPrivate::HashMap;
+using BPrivate::HashString;
+
+// VCard 2.1 standard fields
+
+#define VCARD_ADDRESS              "ADR"
+#define VCARD_BIRTHDAY             "BDAY"
+#define VCARD_DELIVERY_LABEL       "LABEL"
+#define VCARD_EMAIL                "EMAIL"
+#define VCARD_FORMATTED_NAME       "FN"
+#define VCARD_REVISION             "REV"
+#define VCARD_SOUND                "SOUND"
+#define VCARD_TELEPHONE            "TEL"
+#define VCARD_TIME_ZONE            "TZ"
+#define VCARD_TITLE                "TITLE"
+#define VCARD_URL                  "URL"
+#define VCARD_GEOGRAPHIC_POSITION  "GEO"
+#define VCARD_NAME                 "N"
+#define VCARD_NICKNAME             "NICKNAME"
+#define VCARD_NOTE                 "NOTE"
+#define VCARD_ORGANIZATION         "ORG"
+#define VCARD_PHOTO                "PHOTO"
+#define VCARD_VERSION              "VERSION"
+
+// Currently unsupported standard fields
+
+#define VCARD_AGENT                "AGENT"
+#define VCARD_CATEGORIES           "CATEGORIES"
+#define VCARD_CLASS                "CLASS"
+#define VCARD_ROLE                 "ROLE"
+#define VCARD_SORT_STRING          "SORT-STRING"
+#define VCARD_KEY                  "KEY"
+#define VCARD_LOGO                 "LOGO"
+#define VCARD_MAILER               "MAILER"
+#define VCARD_PRODUCT_IDENTIFIER   "PRODID"
+
+// Custom Haiku OS extensions
+
+#define X_VCARD_IM                                     "X-HAIKU-IM"
+#define X_VCARD_PROTOCOLS                      "X-HAIKU-PROTOCOLS"
+#define X_VCARD_SIMPLE_GROUP           "X-HAIKU-SIMPLEGROUP"
+#define X_VCARD_GROUP                          "X-HAIKU-GROUP"
+#define X_VCARD_UID                                    "X-HAIKU-UID"
+
+// Non-Haiku custom fields supported
+
+#define X_VCARD_GENDER                         "X-GENDER"
+#define X_VCARD_ASSISTANT                      "X-ASSISTANT"
+#define X_VCARD_MANAGER                                "X-MANAGER"
+#define X_VCARD_SPOUSE                         "X-SPOUSE"
+
+#define X_VCARD_AIM                                    "X-AIM"
+#define X_VCARD_ICQ                                    "X-ICQ"
+#define X_VCARD_MSN                                    "X-MSN"
+#define X_VCARD_JABBER                         "X-JABBER"
+#define X_VCARD_YAHOO                          "X-YAHOO"
+#define X_VCARD_TWITTER                                "X-TWITTER"
+#define X_VCARD_SKYPE                          "X-SKYPE"
+#define X_VCARD_GADUGADU                       "X-GADUGADU"
+#define X_VCARD_GROUPWISE                      "X-GROUPWISE"
+
+// Unsupported non-Haiku custom fields
+
+#define X_VCARD_SKYPE_USERNAME         "X-SKYPE-USERNAME"
+
+#define X_VCARD_PHONETIC_LAST_NAME     "X-PHONETIC-LAST-NAME"
+#define X_VCARD_PHONETIC_FIRST_NAME "X-PHONETIC-FIRST-NAME"
+
+// VCard <-> BContact defs
+struct fieldMap {
+       const char* key;
+       field_type type;
+       int     op;
+};
+
+struct usageMap {
+       const char* key;
+       field_usage usage;
+};
+// This is a translation table
+// that will be used to fill a map with the purpose to convert
+// fields from BContact to VCard.
+static fieldMap gFieldsMap[] = {
+               // Standard VCard 2.0 fields
+               { VCARD_ADDRESS, B_CONTACT_ADDRESS },
+               { X_VCARD_ASSISTANT, B_CONTACT_ASSISTANT },
+               { VCARD_BIRTHDAY, B_CONTACT_BIRTHDAY },
+               { VCARD_DELIVERY_LABEL, B_CONTACT_DELIVERY_LABEL },
+               { VCARD_EMAIL, B_CONTACT_EMAIL },
+               { VCARD_FORMATTED_NAME, B_CONTACT_FORMATTED_NAME },
+               { X_VCARD_GENDER, B_CONTACT_GENDER },
+               { VCARD_GEOGRAPHIC_POSITION, B_CONTACT_GEO },
+               { X_VCARD_MANAGER, B_CONTACT_MANAGER },
+               { VCARD_NAME, B_CONTACT_NAME },
+               { VCARD_NICKNAME, B_CONTACT_NICKNAME },
+               { VCARD_NOTE, B_CONTACT_NOTE },
+               { VCARD_ORGANIZATION, B_CONTACT_ORGANIZATION },
+               { VCARD_TELEPHONE, B_CONTACT_PHONE },
+               { VCARD_PHOTO, B_CONTACT_PHOTO },
+               { X_VCARD_SPOUSE, B_CONTACT_SPOUSE },
+               { VCARD_SOUND, B_CONTACT_SOUND },
+               { VCARD_TIME_ZONE, B_CONTACT_TIME_ZONE },
+               { VCARD_TITLE, B_CONTACT_TITLE },
+               { VCARD_URL, B_CONTACT_URL },
+               { VCARD_REVISION, B_CONTACT_REV },
+
+               // Custom VCard Haiku fields
+               { X_VCARD_IM, B_CONTACT_IM },
+               { X_VCARD_PROTOCOLS, B_CONTACT_PROTOCOLS },
+               { X_VCARD_SIMPLE_GROUP, B_CONTACT_SIMPLE_GROUP },
+               { X_VCARD_GROUP, B_CONTACT_GROUP },
+               { X_VCARD_UID, B_CONTACT_UID },
+
+               { NULL, 0 }
+};
+
+static usageMap gUsagesMap[] = {
+               // Standard vcard 2.0 usages
+               //{ "",   CONTACT_DATA_CUSTOM },
+               //{ "" ,  CONTACT_DATA_OTHER },
+               { "HOME", CONTACT_DATA_HOME },
+               { "WORK", CONTACT_DATA_WORK },
+               { "PREF", CONTACT_DATA_PREFERRED },
+
+               { "" , CONTACT_NAME_FAMILY },
+               { "" , CONTACT_NAME_GIVEN },
+               { "" , CONTACT_NAME_MIDDLE },
+               { "" , CONTACT_NAME_SUFFIX },
+
+               { "" , CONTACT_NICKNAME_DEFAULT },
+               { "" , CONTACT_NICKNAME_MAIDEN },
+               { "" , CONTACT_NICKNAME_SHORT_NAME },
+               { "" , CONTACT_NICKNAME_INITIALS },
+
+               { "" , CONTACT_EMAIL_MOBILE },
+               { "INTERNET" , CONTACT_EMAIL_INTERNET },
+
+               { "CELL", CONTACT_PHONE_MOBILE },
+               { "FAX", CONTACT_PHONE_FAX },
+               { "PAGER" , CONTACT_PHONE_PAGER },
+               { "" , CONTACT_PHONE_CALLBACK },
+               { "CAR" , CONTACT_PHONE_CAR },
+               { "ISDN" , CONTACT_PHONE_ISDN },
+               { "" , CONTACT_PHONE_RADIO },
+               { "" , CONTACT_PHONE_TELEX },
+               { "" , CONTACT_PHONE_TTY_TDD },
+               { "MODEM" , CONTACT_PHONE_MODEM },
+               { "" , CONTACT_PHONE_ASSISTANT },
+               { "VIDEO" , CONTACT_PHONE_VIDEO },
+               { "VOICE" , CONTACT_PHONE_VOICE },
+               { "MSG", CONTACT_PHONE_MSG },
+
+               { "" , CONTACT_PHOTO_BITMAP },
+
+               { "DOM" , CONTACT_ADDRESS_DOM },
+               { "INTL" , CONTACT_ADDRESS_INTL },
+               { "POSTAL" , CONTACT_ADDRESS_POSTAL },
+               { "PARCEL" , CONTACT_ADDRESS_PARCEL },
+
+               { "WAVE" , CONTACT_SOUND_WAVE },
+               { "PCM" , CONTACT_SOUND_PCM },
+               { "AIFF" , CONTACT_SOUND_AIFF },
+               { "" , CONTACT_SOUND_MP3 },
+               { "" , CONTACT_SOUND_OGG },
+
+               { "X-VCARD-AIM" , CONTACT_IM_AIM },
+               { "X-VCARD-ICQ" , CONTACT_IM_ICQ },
+               { "X-VCARD-MSN" , CONTACT_IM_MSN },
+               { "X-VCARD-JABBER" , CONTACT_IM_JABBER },
+               { "X-VCARD-YAHOO" , CONTACT_IM_YAHOO },
+               { "X-VCARD-TWITTER" , CONTACT_IM_TWITTER },
+               { "X-VCARD-SKYPE" , CONTACT_IM_SKYPE },
+               { "X-VCARD-GADUGADU" , CONTACT_IM_GADUGADU },
+               { "X-VCARD-GROUPWISE" , CONTACT_IM_GROUPWISE },
+               { NULL, 0 }
+       };
+
+// Translation map typedefs
+typedef HashMap<HashKey32<field_type>, BString> OutFieldsMap;
+typedef HashMap<HashKey32<field_usage>, BString> OutUsagesMap;
+
+typedef HashMap<HashString, field_type> InFieldsMap;
+typedef HashMap<HashString, field_usage> InUsagesMap;
+
+#endif
diff --git a/src/add-ons/translators/vcard/VCardTranslator.cpp 
b/src/add-ons/translators/vcard/VCardTranslator.cpp
new file mode 100755
index 0000000..eb741b1
--- /dev/null
+++ b/src/add-ons/translators/vcard/VCardTranslator.cpp
@@ -0,0 +1,313 @@
+#include "VCardTranslator.h"
+
+#include <shared/AutoDeleter.h>
+#include <ObjectList.h>
+
+#include <new>
+#include <stdio.h>
+#include <syslog.h>
+
+#include "VCardParser.h"
+
+
+const char* kTranslatorName = "VCardTranslator";
+const char* kTranslatorInfo = "Translator for VCard files";
+
+#define VCARD_MIME_TYPE "text/x-vCard"
+#define CONTACT_MIME_TYPE "application/x-hcontact"
+
+static const translation_format sInputFormats[] = {
+               {
+               B_CONTACT_FORMAT,
+               B_TRANSLATOR_CONTACT,
+               IN_QUALITY,
+               IN_CAPABILITY,
+               CONTACT_MIME_TYPE,
+               "Haiku binary contact"
+       },
+       {
+               B_VCARD_FORMAT ,
+               B_TRANSLATOR_CONTACT,
+               IN_QUALITY,
+               IN_CAPABILITY,
+               VCARD_MIME_TYPE,
+               "vCard Contact file"
+       }
+};
+
+// The output formats that this translator supports.
+static const translation_format sOutputFormats[] = {
+               {
+               B_CONTACT_FORMAT,
+               B_TRANSLATOR_CONTACT,
+               OUT_QUALITY,
+               OUT_CAPABILITY,
+               CONTACT_MIME_TYPE,
+               "Haiku binary contact"
+       },
+       {
+               B_VCARD_FORMAT ,
+               B_TRANSLATOR_CONTACT,
+               OUT_QUALITY,
+               OUT_CAPABILITY,
+               VCARD_MIME_TYPE,
+               "vCard Contact file"
+       }
+};
+
+// Default settings for the Translator
+static const TranSetting sDefaultSettings[] = {
+};
+
+const uint32 kNumInputFormats = sizeof(sInputFormats) 
+       / sizeof(translation_format);
+const uint32 kNumOutputFormats = sizeof(sOutputFormats)
+       / sizeof(translation_format);
+const uint32 kNumDefaultSettings = sizeof(sDefaultSettings)
+       / sizeof(TranSetting);
+
+// required by the BaseTranslator class
+BTranslator *
+make_nth_translator(int32 n, image_id you, uint32 flags, ...)
+{
+       if (!n)
+               return new (std::nothrow) VCardTranslator();
+
+       return NULL;
+}
+
+
+VCardTranslator::VCardTranslator()
+       :
+       BaseTranslator(kTranslatorName, kTranslatorInfo, 
VCARD_TRANSLATOR_VERSION,
+               sInputFormats, kNumInputFormats, sOutputFormats, 
kNumOutputFormats,
+               "VCardTranslatorSettings", sDefaultSettings, 
kNumDefaultSettings,
+               B_TRANSLATOR_CONTACT, B_VCARD_FORMAT)
+{
+       for (int i = 0; gFieldsMap[i].key != NULL; i++)
+               fFieldsMap.Put(HashKey32<field_type>(gFieldsMap[i].type),
+                       BString(gFieldsMap[i].key));
+
+       for (int i = 0; gUsagesMap[i].key != NULL; i++)
+               fFieldsMap.Put(HashKey32<field_usage>(gUsagesMap[i].usage),
+                       BString(gUsagesMap[i].key));
+}
+
+
+VCardTranslator::~VCardTranslator()
+{
+}
+
+
+status_t
+VCardTranslator::Identify(BPositionIO* inSource,
+       const translation_format* inFormat, BMessage* ioExtension,
+       translator_info* outInfo, uint32 outType)
+{
+       if (!outType)
+               outType = B_CONTACT_FORMAT;
+
+       if (outType != B_CONTACT_FORMAT && outType != B_VCARD_FORMAT)
+               return B_NO_TRANSLATOR;
+
+       BMessage msg;
+       if (outType == B_VCARD_FORMAT && msg.Unflatten(inSource) == B_OK) {
+               msg.PrintToStream();
+               outInfo->type = B_CONTACT_FORMAT;
+               outInfo->group = B_TRANSLATOR_CONTACT;
+               outInfo->quality = IN_QUALITY;
+               outInfo->capability = IN_CAPABILITY;
+               snprintf(outInfo->name, sizeof(outInfo->name), kTranslatorName);
+               strcpy(outInfo->MIME, CONTACT_MIME_TYPE);
+               return B_OK;
+       } else if (outType == B_CONTACT_FORMAT)
+               return _IdentifyVCard(inSource, outInfo);
+
+       return B_NO_TRANSLATOR;
+}
+
+
+status_t
+VCardTranslator::Translate(BPositionIO* inSource, const translator_info* info,
+       BMessage* ioExtension, uint32 outType, BPositionIO* outDestination)
+{
+       if (!outType)
+               outType = B_CONTACT_FORMAT;
+
+       if (outType != B_CONTACT_FORMAT && outType != B_VCARD_FORMAT)
+               return B_NO_TRANSLATOR;
+
+       // add no translation
+       BMessage msg;
+       if (outType == B_VCARD_FORMAT && msg.Unflatten(inSource) == B_OK)
+               return TranslateContact(&msg, ioExtension, outDestination);
+       else if (outType == B_CONTACT_FORMAT)
+               return TranslateVCard(inSource, ioExtension, outDestination);
+
+       return B_ERROR;
+}
+
+
+status_t
+VCardTranslator::TranslateContact(BMessage* inSource, 
+               BMessage* ioExtension, BPositionIO* outDestination)
+{
+       int32 count = 0;
+       type_code code = B_CONTACT_FIELD_TYPE;
+
+       _WriteBegin(outDestination);
+
+       status_t ret = inSource->GetInfo(CONTACT_FIELD_IDENT, &code, &count);
+       if (ret != B_OK)
+               return ret;
+
+       for (int i = 0; i < count; i++) {

[ *** diff truncated: 8985 lines dropped *** ]


############################################################################

Commit:      79d124525e7536819aa456eb39b53a4f87f01f8b
Author:      Barrett <b.vitruvio@xxxxxxxxx>
Date:        Mon Jul 29 16:18:13 2013 UTC
Committer:   Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Sun May 25 01:24:10 2014 UTC

Removed unneeded files.

----------------------------------------------------------------------------

############################################################################

Commit:      c314ba74692fe895a94fdd1519bcb07c63654bcd
Author:      Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date:        Sun May 25 10:55:40 2014 UTC

Build system changes for contact kit in a packaged world.

----------------------------------------------------------------------------

############################################################################

Commit:      afaab8c55db06c1d075655993c4127867542dd6d
Author:      Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date:        Sun May 25 15:04:11 2014 UTC

Also add VCard translator for a package managed world.

----------------------------------------------------------------------------


Other related posts:

  • » [haiku-commits] BRANCH jessicah-github.contacts [afaab8c] in src: apps/people-old apps/people kits/contact add-ons/translators/vcard add-ons/translators/person - jessicah-github . contacts