VCard import

User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

VCard import

Post by Otto »

Hello,
does someone have code for VCard import into dbf file.
http://en.wikipedia.org/wiki/VCard
Thanks in advance
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: VCard import

Post by Antonio Linares »

Otto,

What vcard format are you using ? (from the ones explained in the wikipedia)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: VCard import

Post by Otto »

Hello Antonio,
I think VERSION 2.1 is mostly used at the moment.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: VCard import

Post by nageswaragunupudi »

Here is a simple function that parses VCard text Version 2.1 and returns an array containing 6 elements:
1. Title. 2. WorkPhone, 3. HomePhone, 4. WorkAddr, 5. HomeAddr and 6. Email.
Contents of the array can be stored in dbf or as other form of data.

Code: Select all

function ParseVCard( cText )

   local nVer     := 0
   local aRet     := {}

   cText    := StrBetween( cText, "BEGIN:VCARD", "END:VCARD" )
   cText    := StrTran( cText, Chr(10), Chr(13 ) )
   if Empty( cText )
      MsgInfo( "Not valid VCard Info" )
   else
      nVer     := Val( StrBetween( cText, "VERSION:", Chr(13) ) )
      if nVer == 2.1
         AAdd( aRet, TagInfo( cText, "TITLE:" ) )
         AAdd( aRet, TagInfo( cText, "TEL;WORK;VOICE:" ) )
         AAdd( aRet, TagInfo( cText, "TEL;HOME;VOICE:" ) )
         AAdd( aRet, TagInfo( cText, "ADR;WORK:;;" ) )
         AAdd( aRet, TagInfo( cText, "ADR;HOME:;;" ) )
         AAdd( aRet, TagInfo( cText, "EMAIL;PREF;INTERNET:" ) )
      else
         if nVer > 0
            MsgInfo( "Version " + LTrim( Str( nVer ) ) + " not implemented" )
         endif
      endif
   endif

return aRet

//----------------------------------------------------------------------------//

tatic function TagInfo( cStr, cTag )
return StrBetween( cStr, cTag, Chr( 13 ) )

//----------------------------------------------------------------------------//

static function StrBetween( cStr, cAfter, cBefore )
return BeforAtNum( cBefore, AfterAtNum( cAfter, cStr, 1 ), 1 )

//----------------------------------------------------------------------------//
 
This function can be extended to all versions of VCard and more checks and for fields can be incorporated.
Regards

G. N. Rao.
Hyderabad, India
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: VCard import

Post by James Bott »

Here is Rao's ccode converted to a class. I added a few more items. Using a class allows you to pass the entire oVcard object around to other routines.

In doing the conversion I did discover one big problem. There can be multiple email addresses all with the same tag. The preferred email address has this tag:

EMAIL;PREF;INTERNET:

However this can be followed by multiple email addresses all with this tag:

"EMAIL:INTERNET:"

Since Rao's code depends on there being a unique tag for each item, it won't work for these items--it will always return the first item. I am afraid that the only solution is to rewrite the entire code to read and parse each line sequentially. Maybe someone else has a better idea?

Regards,
James

Code: Select all

// Purpose: VCard class
// Date: 4/30/2013 

#include "fivewin.ch"

function main()
   local cVcard, aVcard, oVcard, cFile

   cFile:= "James Bott.vcf"

   oVcard:= TVcard():new( cFile )

   msgInfo( oVcard:cName )
   
   msgInfo( oVcard:cCompany )

return nil


//---------------------------------------------------------------------------//

class Tvcard
   data cName
   data cTitle
   data cCompany
   data cWorkPhone
   data cWorkFax
   data cHomePhone
   data cWorkAddress
   data cHomeAddress
   data cEmail
   data cEmail2

   Exported:
   method new( cVcard )
   method end() VIRTUAL
   
   Hidden:
   method tagInfo()
   method StrBetween()
endclass

//---------------------------------------------------------------------------//

method new( cVcard ) class TVCARD

   local nVer     := 0
   local aRet     := {}
   local cText    := memoRead( cVcard )

   cText    := ::StrBetween( cText, "BEGIN:VCARD", "END:VCARD" )
   cText    := StrTran( cText, Chr(10), Chr(13 ) )
   if Empty( cText )
      MsgInfo( "Not valid VCard Info" )
   else
      nVer     := Val( ::StrBetween( cText, "VERSION:", Chr(13) ) )
      if nVer == 2.1
         ::cName:= ::TagInfo( cText, "FN:" )
         ::cTitle:= ::TagInfo( cText, "TITLE:" )
         ::cCompany:= ::TagInfo( cText, "ORG:" )
         ::cWorkPhone:= ::TagInfo( cText, "TEL;WORK;VOICE:" )
         ::cWorkFax:= ::TagInfo( cText, "TEL:WORK:FAX:" )
         ::cHomePhone:= ::TagInfo( cText, "TEL;HOME;VOICE:" )
         ::cWorkAddress:= ::TagInfo( cText, "ADR;WORK:;;" )
         ::cHomeAddress:= ::TagInfo( cText, "ADR;HOME:;;" )
         ::cEmail:=  ::TagInfo( cText, "EMAIL;PREF;INTERNET:" )
         ::cEmail2:= ::TagInfo( cText, "EMAIL:INTERNET:" )
      else
         if nVer > 0
            MsgInfo( "VCard Version " + LTrim( Str( nVer ) ) + " not implemented" )
         endif
      endif
   endif

return self

//---------------------------------------------------------------------------//

method tagInfo( cStr, cTag ) Class TVCARD
return ::StrBetween( cStr, cTag, Chr( 13 ) )

//----------------------------------------------------------------------------//

method StrBetween( cStr, cAfter, cBefore ) Class TVCARD
return BeforAtNum( cBefore, AfterAtNum( cAfter, cStr, 1 ), 1 )

//----------------------------------------------------------------------------//

// end of file
 
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: VCard import

Post by Otto »

Hello James,

maybe we can use an array for the attributes.
To fill the array we could look for double dot “:” and then fill the array.

Best regards,
Otto

http://www.imc.org/pdi/pdiproddev.html
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: VCard import

Post by James Bott »

Hi Otto,
maybe we can use an array for the attributes.
Sure.

The issue is that it needs to be completely written to read in every line of the vcard file. I will work on it as time permits.

Regards,
James
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: VCard import

Post by nageswaragunupudi »

Sample VCard reader for vCard versions 2.1, 3.0 and 4.0.
This is under development and worked well with as many samples I could find. By testing with more samples we can improve this.

Code: Select all

/*
*
*  vcard.prg
*  G.N.Rao
*  Apr 30-2013 06:27 PM
*
*/

#include "FiveWin.Ch"
#include "hbcompat.ch"
#include "ord.ch"
#include "xbrowse.ch"

//----------------------------------------------------------------------------//

REQUEST DBFCDX

//----------------------------------------------------------------------------//

function Main()

   local cCard, aInfo
   local oCard
   local cFile

   do while ! Empty( cFile := cGetFile( "VCard (*.vcf) |*.vcf|", "Select a VCard File", ;
                        nil, cFilePath( ExeName() ) ) )

      oCard    := TVCard():New( cFile )
      oCard:Display()
   enddo

return (0)

//----------------------------------------------------------------------------//

init procedure PrgInit

   SET DATE GERMAN
   SET CENTURY ON
   SET TIME FORMAT TO "HH:MM:SS"
   SET EPOCH TO YEAR(DATE())-50

   SET DELETED ON
   SET EXCLUSIVE OFF

   RDDSETDEFAULT( "DBFCDX" )

   XbrNumFormat( 'E', .t. )
   SetKinetic( .f. )
   SetGetColorFocus()

return

//----------------------------------------------------------------------------//

CLASS TVCard

   DATA nVersion  AS NUMERIC
   DATA lValid    AS LOGICAL
   //
   DATA cFile
   DATA cName, cNameFmt, cAdrHome, cAdrWork, cAdrHomeFmt, cAdrWorkFmt, ;
      cTitle, cKind, cGender, cOrg, cRole, cNickName, cNote, ;
      cPhoneHome, cPhoneWork, cFaxHome, cFaxWork, cPhoneCell, ;
      cEmail, cPhotoRef, cPhotoBuf ;
      AS CHARACTER
   DATA dDOB AS DATE INIT CTOD( '' )
   //
   //
   METHOD New( cFile ) CONSTRUCTOR
   METHOD ReadFile( cFile )   INLINE ::ReadCardText( MemoRead( cFile ) )
   METHOD ReadCardText( cText )
   METHOD Display()
   //
   METHOD SaveToDBF() VIRTUAL
   METHOD ReadFromDBF() VIRTUAL
   METHOD SaveAsText() VIRTUAL
   METHOD RestoreFromText( cText ) VIRTUAL
   METHOD WriteVCard() VIRTUAL

ENDCLASS

//----------------------------------------------------------------------------//

METHOD New( cFile ) CLASS TVCard

   if ! Empty( cFile )
      if Len( cFile ) < 256 .and. Lower( cFileExt( cFile ) ) == "vcf"
         ::cFile     := cFileNoPath( cFile )
         ::ReadFile( cFile )
      else
         ::ReadCardText( cFile )
      endif
   endif

return Self

//----------------------------------------------------------------------------//

METHOD ReadCardText( cText ) CLASS TVCard

   local aLines, aLine
   local c, cVal, n, nAt
   local lAssigned, cAttr

   cText    := StrBetween( cText, "BEGIN:VCARD", "END:VCARD" )
   cText    := StrTran( cText, CRLF + ' ', '' )
   cText    := StrTran( cText, CRLF, Chr(10) )
   cText    := StrTran( cText, Chr(10) + ' ', '' )
   cText    := RemAll( cText, 10 )

   aLines        := HB_ATokens( cText, Chr(10) )
   for n := 1 to Len( aLines )
      c     := aLines[ n ]
      aLines[ n ] := { Upper( BeforAtNum( ':', c, 1 ) ), AfterAtNum( ':', c, 1 ), "" }
      if aLines[ n, 1 ] = "PHOTO" .and. ;
         "ENCODING" $ aLines[ n, 1 ] .and. ;
         "BASE64"   $ aLines[ n, 1 ]

         aLines[ n, 2 ] := DecodeBase64( aLines[ n, 2 ] )
      endif
   next n
   if aLines[ 1, 1 ] = "VERSION"
      ::nVersion  := Val( aLines[ 1, 2 ] )
   endif
   if ::nVersion == 2.1 .or. ::nVersion == 3 .or. ::nVersion == 4
      ::lValid    := .t.
   endif
   if ! ::lValid
      return Self
   endif
   ADel( aLines, 1, .t. )

   for n := 1 to Len( aLines )
      if !( ';' $ aLines[ n, 1 ] )
         aLines[ n, 1 ] += ';'
      endif
      c     := aLines[ n, 1 ]
      if ( nAt := At( '.', c ) ) > 0 .and. nAt < At( ';', c )
         aLines[ n, 3 ] := Trim( BeforAtNum( c, '.', 1 ) )  // Group
         aLines[ n, 1 ] := LTrim( AfterAtNum( c, '.', 1 ) )
      endif
   next


   for each aLine in aLines
      c     := aLine[ 1 ]
      cVal  := aLine[ 2 ]

      lAssigned   := .f.
      for each cAttr in { "TITLE", "GENDER", "KIND", "ORG", "ROLE", "NICKNAME", "NOTE" }
         if c = cAttr + ';'
            OSend( Self, "_c" + cAttr, cVal )
            lAssigned := .t.
            exit
         endif
      next
      if lAssigned
         loop
      endif
      //
      do case
      case c = 'N;'  ; ::cName      := cVal
      case c = 'FN;' ; ::cNameFmt   := cVal
      case c = 'ADR;'
         if "WORK" $ c
            ::cAdrWork     := cVal
         endif
         if "HOME" $ c .or. !( "WORK" $ c )
            ::cAdrHome     := cVal
         endif
      case c = 'LABEL;'
         cVal  := StrTran( cVal, "=0A=0D", CRLF )
         cVal  := StrTran( cVal, "=0D=0A", CRLF )
         cVal  := StrTran( cVal, "=20", " " )
         cVal  := FW_ValToExp( cVal )
         if "WORK" $ c
            ::cAdrWorkFmt     := cVal
         endif
         if "HOME" $ c .or. !( "WORK" $ c )
            ::cAdrHomeFmt     := cVal
         endif
      case c = 'TEL;'
         if "CELL" $ c
            ::cPhoneCell   := cVal
         else
            if "WORK" $ c
               if "FAX" $ c
                  ::cFaxWork     := cVal
               else
                  ::cPhoneWork   := cVal
               endif
            endif
            if "HOME" $ c .or. !( "WORK" $ c )
               if "FAX" $ c
                  ::cFaxHome     := cVal
               else
                  ::cPhoneHome   := cVal
               endif
            endif
         endif
      case c = 'EMAIL;'
         ::cEmail    := cVal
      case c = 'PHOTO;'
         if IsBinaryData( cVal )
            ::cPhotoBuf    := cVal
         else
            ::cPhotoRef    := cVal
         endif
      case c = 'BDAY;'
         c     := cVal
         ::dDOB  := STOD( Left( StrTran( StrTran( c, '-', '' ), '/', '' ), 8 ) )
      endcase
   next

return Self

//----------------------------------------------------------------------------//

METHOD Display() CLASS TVCard

   local oDlg, oFont, oImage
   local nRow, cAdrHomeFmt := '', cAdrWorkFmt := ''

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
   DEFINE DIALOG oDlg SIZE 800,500 PIXEL FONT oFont ;
      TITLE ::cFile + " (Version : " + LTrim( Str( ::nVersion ) ) + " )"

   if ! Empty( ::cAdrHomeFmt )
      cAdrHomeFmt    := &( ::cAdrHomeFmt )
   endif

   if ! Empty( ::cAdrWorkFmt )
      cAdrWorkFmt    := &( ::cAdrWorkFmt )
   endif**

   nRow  := 10
   @ nRow,10 SAY "NameFmt : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cNameFmt SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
/*
   nRow  += 12
   @ nRow,10 SAY "Name : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cName SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
*/
   nRow  += 12
   @ nRow,10 SAY "Gender : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cGender SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "Title : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cTitle SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "Role : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cRole SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "Orgnisn : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cOrg SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "DateOfBirth : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::dDOB SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "PHONES (Work) : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cPhoneWork SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "(Home) : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cPhoneHome SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "FAX (Work) : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cFaxWork SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "(Home) : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cFaxHome SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "CellPhone : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cPhoneCell SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "Email : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cEmail SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
/*
   nRow  += 12
   @ nRow,10 SAY "ADDR (Work) : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cAdrWork SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 12
   @ nRow,10 SAY "(Home) : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY ::cAdrHome SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
*/
   nRow  += 12
   @ nRow,10 SAY "MailWork : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY cAdrWorkFmt SIZE 200,30 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 32
   @ nRow,10 SAY "MailHome : " SIZE 50,10 PIXEL OF oDlg RIGHT
   @ nRow,61 SAY cAdrHomeFmt SIZE 200,30 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
   nRow  += 30

   if ! Empty( ::cPhotoBuf )
      @ 10,290 IMAGE oImage SIZE 100,100 PIXEL OF oDlg
      WITH OBJECT oImage
         :LoadFromMemory( ::cPhotoBuf )
         :Refresh()
      END
   elseif ! Empty( ::cPhotoRef )
      @ 10,290 SAY ::cPhotoRef SIZE 100,100 PIXEL OF oDlg COLOR CLR_HRED,CLR_WHITE BORDER
   endif

   @ nRow-14,350 BUTTON "Close" SIZE 40,14 PIXEL OF oDlg ACTION oDlg:End()

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

   // QuickDisplay
   XBrowse( Self )


return nil

//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//

static function StrBetween( cStr, cAfter, cBefore, nOccur )
return BeforAtNum( cBefore, AfterAtNum( cAfter, cStr, IfNil( nOccur, 1 ) ), 1 )

//----------------------------------------------------------------------------//

static function GetXmlTag( cText, cTag, nOccur )

   local cRet     := nil
   local c, n1, n2

   n1    := At( '<' + cTag + '>',  cText )
   n2    := At( '<' + cTag + '/>', cText  )
   if n2 > 0 .and. n2 < n1
      cRet     := ""
      cText    := SubStr( cText, n2 + Len( '<' + cTag + '/>' ) + 1 )
   elseif n1 > 0
      c        := SubStr( cText, n1 + Len( '<' + cTag + '>' ) + 1 )
      n2       := At( '</' + cTag + '>', c )
      if n2 > 0
         cRet  := Left( c, n2 - 1 )
         cText := SubStr( c, n2 + Len( '<' + cTag + '/>' ) + 1 )
      endif
   endif

return cRet  // nil -> tag not found, '' -> empty value

//----------------------------------------------------------------------------//

function DecodeBase64( cIn )

   local cOut  := ""

   do while ! Empty( cIn )
      cOut  += b64_sub( Left( cIn, 4 ) )
      cIn   := SubStr( cIn, 5 )
   enddo

return cOut

//----------------------------------------------------------------------------//

static function b64_sub( c4 )

   static cRef := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

   local a,b,c,d
   local x,y,z
   local cRet

   c4 := Left( c4 + "==", 4 )
   a  := At( SubStr( c4, 1, 1 ), cRef ) - 1
   b  := At( SubStr( c4, 2, 1 ), cRef ) - 1
   c  := At( SubStr( c4, 3, 1 ), cRef ) - 1
   d  := At( SubStr( c4, 4, 1 ), cRef ) - 1

   x  := a * 4
   x  += Int( b / 16 )
   if c == -1
      return Chr( x )
   endif
   b  := b % 16
   y  := b * 16
   y  += Int( c / 4 )
   if d == -1
      return Chr( x ) + Chr( y )
   endif
   c  := c % 4
   z  := c * 64
   z  += d

return Chr( x ) + Chr( y ) + Chr( z )

//----------------------------------------------------------------------------//
 
Here is a sample vcf file for testing:

Code: Select all

BEGIN:VCARD
VERSION:2.1
N:Gump;Forrest
FN:Forrest Gump
ORG:Bubba Gump Shrimp Co.
TITLE:Shrimp Man
GENDER:M
PHOTO;TYPE=JPEG;ENCODING=BASE64:
 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
 4K0bWnxxm+fY/9k=

TEL;WORK;VOICE:(111) 555-1212
TEL;HOME;VOICE:(404) 555-1212
ADR;WORK:;;100 Waters Edge;Baytown;LA;30314;United States of America
LABEL;WORK;ENCODING=QUOTED-PRINTABLE:100 Waters Edge=0D=0ABaytown, LA 30314=0D=0AUnited States of 

America
ADR;HOME:;;42 Plantation St.;Baytown;LA;30314;United States of America
LABEL;HOME;ENCODING=QUOTED-PRINTABLE:42 Plantation St.=0D=0ABaytown, LA 30314=0D=0AUnited States of 

America
BDAY;:1972-10-15
EMAIL;PREF;INTERNET:forrestgump@example.com
REV:20080424T195243Z
END:VCARD
 
Display screen shot by the program
Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: VCard import

Post by James Bott »

Rao,

Wow, great work. I was working on expanding the class I started, but I see you beat me to it.

I do wonder why you use static functions instead of protected methods? I have found static functions to be a problem when trying to subclass in other FW classes.

Also, why the regular function instead of a protected method?

And, I haven't tested this yet, but it looks like your class cannot detect the preferred email address. Is this correct?

Again nice class.

James
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: VCard import

Post by nageswaragunupudi »

I do wonder why you use static functions instead of protected methods? I have found static functions to be a problem when trying to subclass in other FW classes.

Also, why the regular function instead of a protected method?
You have raised very valid issues.

First, let me answer these points with reference to this Vcard class.
These functions/static functions are not part of the class. For my personal use they are separate library functions, to be used as library functions from any other applications. I included them here (with some changes in names and code) to make the sample complete. In some cases we can remove "static" restriction.

Now about FWH. I see there is a case to move some functions & static functions as methods (protected or public) so that derived classes can use them. We shall keep this in mind while making further revisions from now onwards.
And, I haven't tested this yet, but it looks like your class cannot detect the preferred email address. Is this correct?
You are right. This needs modification. You will be helping to improve the class by such suggestions and reporting bugs.
Regards

G. N. Rao.
Hyderabad, India
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: VCard import

Post by James Bott »

Rao,
These functions/static functions are not part of the class. For my personal use they are separate library functions, to be used as library functions from any other applications. I included them here (with some changes in names and code) to make the sample complete. In some cases we can remove "static" restriction.
OK, I understand. However, for the rest of us they are part of the class, so it would be better if those static functions were defined as protected methods. Then the class is still fully encapsulated and we can also subclass and use those methods if needed. And, of course, they won't affect the use of your library with the same routines as functions.

Regards,
James
StefanHaupt
Posts: 824
Joined: Thu Oct 13, 2005 7:39 am
Location: Germany

Re: VCard import

Post by StefanHaupt »

Rao,

Code: Select all

for each cAttr in { "TITLE", "GENDER", "KIND", "ORG", "ROLE", "NICKNAME", "NOTE" }
         if c = cAttr + ';'
            OSend( Self, "_c" + cAttr, cVal )  // ???
            lAssigned := .t.
            exit
         endif
next
could you please explain what OSend (..) does in this code snippet ? I didn´t find any docs about OSend ().

Thanks.
kind regards
Stefan
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: VCard import

Post by nageswaragunupudi »

OSend(...) is an FW function.

OSend( oObj, cvar ) is equivalent to oObj:cvar

OSend( oObj, _cvar, uVal ) is equivalent to oObj:cvar := uVal
Regards

G. N. Rao.
Hyderabad, India
StefanHaupt
Posts: 824
Joined: Thu Oct 13, 2005 7:39 am
Location: Germany

Re: VCard import

Post by StefanHaupt »

OK, thanks
kind regards
Stefan
Frafive
Posts: 189
Joined: Wed Apr 05, 2006 9:48 pm

Re: VCard import

Post by Frafive »

Hola


Para exportar a Vcard ? alguien tiene algo hecho.

Un saludo
Gabriel
Post Reply