• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KTNEF Library

formatter.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00003     Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00004     Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00035 #include "formatter.h"
00036 #include "ktnefparser.h"
00037 #include "ktnefmessage.h"
00038 #include "ktnefdefs.h"
00039 
00040 #include <kpimutils/email.h>
00041 #include <kabc/phonenumber.h>
00042 #include <kabc/vcardconverter.h>
00043 #include <kabc/stdaddressbook.h>
00044 #include <kcal/incidenceformatter.h>
00045 #include <kcal/calendar.h>
00046 #include <kcal/calendarlocal.h>
00047 #include <kcal/icalformat.h>
00048 
00049 #include <klocale.h>
00050 #include <kdatetime.h>
00051 
00052 #include <QtCore/QBuffer>
00053 
00054 #include <time.h>
00055 
00056 using namespace KCal;
00057 using namespace KTnef;
00058 
00059 /*******************************************************************
00060  *  Helper functions for the msTNEF -> VPart converter
00061  *******************************************************************/
00062 
00063 //-----------------------------------------------------------------------------
00064 //@cond IGNORE
00065 static QString stringProp( KTNEFMessage *tnefMsg, const quint32 &key,
00066                            const QString &fallback = QString())
00067 {
00068   return tnefMsg->findProp( key < 0x10000 ? key & 0xFFFF : key >> 16,
00069                             fallback );
00070 }
00071 
00072 static QString sNamedProp( KTNEFMessage *tnefMsg, const QString &name,
00073                            const QString &fallback = QString() )
00074 {
00075   return tnefMsg->findNamedProp( name, fallback );
00076 }
00077 
00078 struct save_tz {
00079   char *old_tz;
00080   char *tz_env_str;
00081 };
00082 
00083 /* temporarily go to a different timezone */
00084 static struct save_tz set_tz( const char *_tc )
00085 {
00086   const char *tc = _tc?_tc:"UTC";
00087 
00088   struct save_tz rv;
00089 
00090   rv.old_tz = 0;
00091   rv.tz_env_str = 0;
00092 
00093   //kDebug(5975) << "set_tz(), timezone before =" << timezone;
00094 
00095   char *tz_env = 0;
00096   if ( getenv( "TZ" ) ) {
00097     tz_env = strdup( getenv( "TZ" ) );
00098     rv.old_tz = tz_env;
00099   }
00100   char *tmp_env = (char*)malloc( strlen( tc ) + 4 );
00101   strcpy( tmp_env, "TZ=" );
00102   strcpy( tmp_env+3, tc );
00103   putenv( tmp_env );
00104 
00105   rv.tz_env_str = tmp_env;
00106 
00107   /* tmp_env is not free'ed -- it is part of the environment */
00108 
00109   tzset();
00110   //kDebug(5975) << "set_tz(), timezone after =" << timezone;
00111 
00112   return rv;
00113 }
00114 
00115 /* restore previous timezone */
00116 static void unset_tz( struct save_tz old_tz )
00117 {
00118   if ( old_tz.old_tz ) {
00119     char *tmp_env = (char*)malloc( strlen( old_tz.old_tz ) + 4 );
00120     strcpy( tmp_env, "TZ=" );
00121     strcpy( tmp_env+3, old_tz.old_tz );
00122     putenv( tmp_env );
00123     /* tmp_env is not free'ed -- it is part of the environment */
00124     free( old_tz.old_tz );
00125   } else {
00126     /* clear TZ from env */
00127     putenv( strdup("TZ") );
00128   }
00129   tzset();
00130 
00131   /* is this OK? */
00132   if ( old_tz.tz_env_str ) {
00133     free( old_tz.tz_env_str );
00134   }
00135 }
00136 
00137 static KDateTime utc2Local( const KDateTime &utcdt )
00138 {
00139   struct tm tmL;
00140 
00141   save_tz tmp_tz = set_tz("UTC");
00142   time_t utc = utcdt.toTime_t();
00143   unset_tz( tmp_tz );
00144 
00145   localtime_r( &utc, &tmL );
00146   return KDateTime( QDate( tmL.tm_year+1900, tmL.tm_mon+1, tmL.tm_mday ),
00147                     QTime( tmL.tm_hour, tmL.tm_min, tmL.tm_sec ) );
00148 }
00149 
00150 static KDateTime pureISOToLocalQDateTime( const QString &dtStr,
00151                                           bool bDateOnly = false )
00152 {
00153   QDate tmpDate;
00154   QTime tmpTime;
00155   int year, month, day, hour, minute, second;
00156 
00157   if ( bDateOnly ) {
00158     year = dtStr.left( 4 ).toInt();
00159     month = dtStr.mid( 4, 2 ).toInt();
00160     day = dtStr.mid( 6, 2 ).toInt();
00161     hour = 0;
00162     minute = 0;
00163     second = 0;
00164   } else {
00165     year = dtStr.left( 4 ).toInt();
00166     month = dtStr.mid( 4, 2 ).toInt();
00167     day = dtStr.mid( 6, 2 ).toInt();
00168     hour = dtStr.mid( 9, 2 ).toInt();
00169     minute = dtStr.mid( 11, 2 ).toInt();
00170     second = dtStr.mid( 13, 2 ).toInt();
00171   }
00172   tmpDate.setYMD( year, month, day );
00173   tmpTime.setHMS( hour, minute, second );
00174 
00175   if ( tmpDate.isValid() && tmpTime.isValid() ) {
00176     KDateTime dT = KDateTime( tmpDate, tmpTime );
00177 
00178     if ( !bDateOnly ) {
00179       // correct for GMT ( == Zulu time == UTC )
00180       if (dtStr.at(dtStr.length()-1) == 'Z') {
00181         //dT = dT.addSecs( 60 * KRFCDate::localUTCOffset() );
00182         //localUTCOffset( dT ) );
00183         dT = utc2Local( dT );
00184       }
00185     }
00186     return dT;
00187   } else {
00188     return KDateTime();
00189   }
00190 }
00191 //@endcond
00192 
00193 QString KTnef::msTNEFToVPart( const QByteArray &tnef )
00194 {
00195   bool bOk = false;
00196 
00197   KTNEFParser parser;
00198   QByteArray b( tnef );
00199   QBuffer buf( &b );
00200   CalendarLocal cal ( KDateTime::UTC );
00201   KABC::Addressee addressee;
00202   ICalFormat calFormat;
00203   Event *event = new Event();
00204 
00205   if ( parser.openDevice( &buf ) ) {
00206     KTNEFMessage *tnefMsg = parser.message();
00207     //QMap<int,KTNEFProperty*> props = parser.message()->properties();
00208 
00209     // Everything depends from property PR_MESSAGE_CLASS
00210     // (this is added by KTNEFParser):
00211     QString msgClass = tnefMsg->findProp( 0x001A, QString(), true )
00212       .toUpper();
00213     if ( !msgClass.isEmpty() ) {
00214       // Match the old class names that might be used by Outlook for
00215       // compatibility with Microsoft Mail for Windows for Workgroups 3.1.
00216       bool bCompatClassAppointment = false;
00217       bool bCompatMethodRequest = false;
00218       bool bCompatMethodCancled = false;
00219       bool bCompatMethodAccepted = false;
00220       bool bCompatMethodAcceptedCond = false;
00221       bool bCompatMethodDeclined = false;
00222       if ( msgClass.startsWith( "IPM.MICROSOFT SCHEDULE." ) ) {
00223         bCompatClassAppointment = true;
00224         if ( msgClass.endsWith( ".MTGREQ" ) )
00225           bCompatMethodRequest = true;
00226         if ( msgClass.endsWith( ".MTGCNCL" ) )
00227           bCompatMethodCancled = true;
00228         if ( msgClass.endsWith( ".MTGRESPP" ) )
00229           bCompatMethodAccepted = true;
00230         if ( msgClass.endsWith( ".MTGRESPA" ) )
00231           bCompatMethodAcceptedCond = true;
00232         if ( msgClass.endsWith( ".MTGRESPN" ) )
00233           bCompatMethodDeclined = true;
00234       }
00235       bool bCompatClassNote = ( msgClass == "IPM.MICROSOFT MAIL.NOTE" );
00236 
00237       if ( bCompatClassAppointment || "IPM.APPOINTMENT" == msgClass ) {
00238         // Compose a vCal
00239         bool bIsReply = false;
00240         QString prodID = "-//Microsoft Corporation//Outlook ";
00241         prodID += tnefMsg->findNamedProp( "0x8554", "9.0" );
00242         prodID += "MIMEDIR/EN\n";
00243         prodID += "VERSION:2.0\n";
00244         calFormat.setApplication( "Outlook", prodID );
00245 
00246         iTIPMethod method;
00247         if ( bCompatMethodRequest )
00248           method = iTIPRequest;
00249         else if ( bCompatMethodCancled )
00250           method = iTIPCancel;
00251         else if ( bCompatMethodAccepted || bCompatMethodAcceptedCond ||
00252                  bCompatMethodDeclined ) {
00253           method = iTIPReply;
00254           bIsReply = true;
00255         } else {
00256           // pending(khz): verify whether "0x0c17" is the right tag ???
00257           //
00258           // at the moment we think there are REQUESTS and UPDATES
00259           //
00260           // but WHAT ABOUT REPLIES ???
00261           //
00262           //
00263 
00264           if ( tnefMsg->findProp(0x0c17) == "1" ) {
00265             bIsReply = true;
00266           }
00267           method = iTIPRequest;
00268         }
00269 
00271         ScheduleMessage schedMsg( event, method, ScheduleMessage::Unknown );
00272 
00273         QString sSenderSearchKeyEmail( tnefMsg->findProp( 0x0C1D ) );
00274 
00275         if ( !sSenderSearchKeyEmail.isEmpty() ) {
00276           int colon = sSenderSearchKeyEmail.indexOf( ':' );
00277           // May be e.g. "SMTP:KHZ@KDE.ORG"
00278           if ( sSenderSearchKeyEmail.indexOf( ':' ) == -1 ) {
00279             sSenderSearchKeyEmail.remove( 0, colon+1 );
00280           }
00281         }
00282 
00283         QString s( tnefMsg->findProp( 0x0e04 ) );
00284         QStringList attendees = s.split( ';' );
00285         if ( attendees.count() ) {
00286           for ( QStringList::Iterator it = attendees.begin();
00287                it != attendees.end(); ++it ) {
00288             // Skip all entries that have no '@' since these are
00289             // no mail addresses
00290             if ( (*it).indexOf( '@' ) == -1 ) {
00291               s = (*it).trimmed();
00292 
00293               Attendee *attendee = new Attendee( s, s, true );
00294               if ( bIsReply ) {
00295                 if ( bCompatMethodAccepted )
00296                   attendee->setStatus( Attendee::Accepted );
00297                 if ( bCompatMethodDeclined )
00298                   attendee->setStatus( Attendee::Declined );
00299                 if ( bCompatMethodAcceptedCond )
00300                   attendee->setStatus( Attendee::Tentative );
00301               } else {
00302                 attendee->setStatus( Attendee::NeedsAction );
00303                 attendee->setRole( Attendee::ReqParticipant );
00304               }
00305               event->addAttendee( attendee );
00306             }
00307           }
00308         } else {
00309           // Oops, no attendees?
00310           // This must be old style, let us use the PR_SENDER_SEARCH_KEY.
00311           s = sSenderSearchKeyEmail;
00312           if ( !s.isEmpty() ) {
00313             Attendee *attendee = new Attendee( QString(), QString(), true );
00314             if ( bIsReply ) {
00315               if ( bCompatMethodAccepted )
00316                 attendee->setStatus( Attendee::Accepted );
00317               if ( bCompatMethodAcceptedCond )
00318                 attendee->setStatus( Attendee::Declined );
00319               if ( bCompatMethodDeclined )
00320                 attendee->setStatus( Attendee::Tentative );
00321             } else {
00322               attendee->setStatus( Attendee::NeedsAction );
00323               attendee->setRole( Attendee::ReqParticipant );
00324             }
00325             event->addAttendee( attendee );
00326           }
00327         }
00328         s = tnefMsg->findProp( 0x0c1f ); // look for organizer property
00329         if ( s.isEmpty() && !bIsReply ) {
00330           s = sSenderSearchKeyEmail;
00331         }
00332         // TODO: Use the common name?
00333         if ( !s.isEmpty() ) {
00334           event->setOrganizer( s );
00335         }
00336 
00337         s = tnefMsg->findProp( 0x8516 ).replace( QChar( '-' ), QString() )
00338           .replace( QChar( ':' ), QString() );
00339         event->setDtStart( KDateTime::fromString( s ) ); // ## Format??
00340 
00341         s = tnefMsg->findProp( 0x8517 ).replace( QChar( '-' ), QString() )
00342           .replace( QChar( ':' ), QString() );
00343         event->setDtEnd( KDateTime::fromString( s ) );
00344 
00345         s = tnefMsg->findProp( 0x8208 );
00346         event->setLocation( s );
00347 
00348         // is it OK to set this to OPAQUE always ??
00349         //vPart += "TRANSP:OPAQUE\n"; ###FIXME, portme!
00350         //vPart += "SEQUENCE:0\n";
00351 
00352         // is "0x0023" OK  -  or should we look for "0x0003" ??
00353         s = tnefMsg->findProp( 0x0023 );
00354         event->setUid( s );
00355 
00356         // PENDING(khz): is this value in local timezone? Must it be
00357         // adjusted? Most likely this is a bug in the server or in
00358         // Outlook - we ignore it for now.
00359         s = tnefMsg->findProp( 0x8202 ).replace( QChar( '-' ), QString() )
00360           .replace( QChar( ':' ), QString() );
00361         // ### kcal always uses currentDateTime()
00362         // event->setDtStamp(QDateTime::fromString(s));
00363 
00364         s = tnefMsg->findNamedProp( "Keywords" );
00365         event->setCategories( s );
00366 
00367         s = tnefMsg->findProp( 0x1000 );
00368         event->setDescription( s );
00369 
00370         s = tnefMsg->findProp( 0x0070 );
00371         event->setSummary( s );
00372 
00373         s = tnefMsg->findProp( 0x0026 );
00374         event->setPriority( s.toInt() );
00375 
00376         // is reminder flag set ?
00377         if (!tnefMsg->findProp(0x8503).isEmpty()) {
00378           Alarm *alarm = new Alarm( event );
00379           KDateTime highNoonTime =
00380             pureISOToLocalQDateTime( tnefMsg->findProp( 0x8502 )
00381                                      .replace( QChar( '-' ), "" )
00382                                      .replace( QChar( ':' ), "" ) );
00383           KDateTime wakeMeUpTime =
00384             pureISOToLocalQDateTime( tnefMsg->findProp( 0x8560, "" )
00385                                      .replace( QChar( '-' ), "" )
00386                                      .replace( QChar( ':' ), "" ) );
00387           alarm->setTime( wakeMeUpTime );
00388 
00389           if ( highNoonTime.isValid() && wakeMeUpTime.isValid() ) {
00390             alarm->setStartOffset( Duration( highNoonTime, wakeMeUpTime ) );
00391           } else {
00392             // default: wake them up 15 minutes before the appointment
00393             alarm->setStartOffset( Duration( 15*60 ) );
00394           }
00395           alarm->setDisplayAlarm( i18n( "Reminder" ) );
00396 
00397           // Sorry: the different action types are not known (yet)
00398           //        so we always set 'DISPLAY' (no sounds, no images...)
00399           event->addAlarm( alarm );
00400         }
00401         cal.addEvent( event );
00402         bOk = true;
00403         // we finished composing a vCal
00404       } else if ( bCompatClassNote || "IPM.CONTACT" == msgClass ) {
00405         addressee.setUid( stringProp( tnefMsg, attMSGID ) );
00406         addressee.setFormattedName( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME ) );
00407         addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL1EMAILADDRESS ), true );
00408         addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL2EMAILADDRESS ), false );
00409         addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL3EMAILADDRESS ), false );
00410         addressee.insertCustom( "KADDRESSBOOK", "X-IMAddress",
00411                                 sNamedProp( tnefMsg, MAPI_TAG_CONTACT_IMADDRESS ) );
00412         addressee.insertCustom( "KADDRESSBOOK", "X-SpousesName",
00413                                 stringProp( tnefMsg, MAPI_TAG_PR_SPOUSE_NAME ) );
00414         addressee.insertCustom( "KADDRESSBOOK", "X-ManagersName",
00415                                 stringProp( tnefMsg, MAPI_TAG_PR_MANAGER_NAME ) );
00416         addressee.insertCustom( "KADDRESSBOOK", "X-AssistantsName",
00417                                 stringProp( tnefMsg, MAPI_TAG_PR_ASSISTANT ) );
00418         addressee.insertCustom( "KADDRESSBOOK", "X-Department",
00419                                 stringProp( tnefMsg, MAPI_TAG_PR_DEPARTMENT_NAME ) );
00420         addressee.insertCustom( "KADDRESSBOOK", "X-Office",
00421                                 stringProp( tnefMsg, MAPI_TAG_PR_OFFICE_LOCATION ) );
00422         addressee.insertCustom( "KADDRESSBOOK", "X-Profession",
00423                                 stringProp( tnefMsg, MAPI_TAG_PR_PROFESSION ) );
00424 
00425         QString s = tnefMsg->findProp( MAPI_TAG_PR_WEDDING_ANNIVERSARY )
00426           .replace( QChar( '-' ), QString() )
00427           .replace( QChar( ':' ), QString() );
00428         if ( !s.isEmpty() ) {
00429           addressee.insertCustom( "KADDRESSBOOK", "X-Anniversary", s );
00430         }
00431 
00432         addressee.setUrl( KUrl( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_WEBPAGE ) ) );
00433 
00434         // collect parts of Name entry
00435         addressee.setFamilyName( stringProp( tnefMsg, MAPI_TAG_PR_SURNAME ) );
00436         addressee.setGivenName( stringProp( tnefMsg, MAPI_TAG_PR_GIVEN_NAME ) );
00437         addressee.setAdditionalName( stringProp( tnefMsg, MAPI_TAG_PR_MIDDLE_NAME ) );
00438         addressee.setPrefix( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME_PREFIX ) );
00439         addressee.setSuffix( stringProp( tnefMsg, MAPI_TAG_PR_GENERATION ) );
00440 
00441         addressee.setNickName( stringProp( tnefMsg, MAPI_TAG_PR_NICKNAME ) );
00442         addressee.setRole( stringProp( tnefMsg, MAPI_TAG_PR_TITLE ) );
00443         addressee.setOrganization( stringProp( tnefMsg, MAPI_TAG_PR_COMPANY_NAME ) );
00444         /*
00445         the MAPI property ID of this (multiline) )field is unknown:
00446         vPart += stringProp(tnefMsg, "\n","NOTE", ... , "" );
00447         */
00448 
00449         KABC::Address adr;
00450         adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_PO_BOX ) );
00451         adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STREET ) );
00452         adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_CITY ) );
00453         adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STATE_OR_PROVINCE ) );
00454         adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_POSTAL_CODE ) );
00455         adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_COUNTRY ) );
00456         adr.setType( KABC::Address::Home );
00457         addressee.insertAddress( adr );
00458 
00459         adr.setPostOfficeBox( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOBOX ) );
00460         adr.setStreet( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTREET ) );
00461         adr.setLocality( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCITY ) );
00462         adr.setRegion( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTATE ) );
00463         adr.setPostalCode( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOSTALCODE ) );
00464         adr.setCountry( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCOUNTRY ) );
00465         adr.setType( KABC::Address::Work );
00466         addressee.insertAddress( adr );
00467 
00468         adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_PO_BOX ) );
00469         adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STREET ) );
00470         adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_CITY ) );
00471         adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STATE_OR_PROVINCE ) );
00472         adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_POSTAL_CODE ) );
00473         adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_COUNTRY ) );
00474         adr.setType( KABC::Address::Dom );
00475         addressee.insertAddress( adr );
00476 
00477         // problem: the 'other' address was stored by KOrganizer in
00478         //          a line looking like the following one:
00479         // vPart += "\nADR;TYPE=dom;TYPE=intl;TYPE=parcel;TYPE=postal;TYPE=work;TYPE=home:other_pobox;;other_str1\nother_str2;other_loc;other_region;other_pocode;other_country
00480 
00481         QString nr;
00482         nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_TELEPHONE_NUMBER );
00483         addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Home ) );
00484         nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_TELEPHONE_NUMBER );
00485         addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Work ) );
00486         nr = stringProp( tnefMsg, MAPI_TAG_PR_MOBILE_TELEPHONE_NUMBER );
00487         addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Cell ) );
00488         nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_FAX_NUMBER );
00489         addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ) );
00490         nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_FAX_NUMBER );
00491         addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work ) );
00492 
00493         s = tnefMsg->findProp( MAPI_TAG_PR_BIRTHDAY )
00494           .replace( QChar( '-' ), QString() )
00495           .replace( QChar( ':' ), QString() );
00496         if ( !s.isEmpty() ) {
00497           addressee.setBirthday( QDateTime::fromString( s ) );
00498         }
00499 
00500         bOk = ( !addressee.isEmpty() );
00501       } else if ( "IPM.NOTE" == msgClass ) {
00502 
00503       } // else if ... and so on ...
00504     }
00505   }
00506 
00507   // Compose return string
00508   QString iCal = calFormat.toString( &cal );
00509   if ( !iCal.isEmpty() ) {
00510     // This was an iCal
00511     return iCal;
00512   }
00513 
00514   // Not an iCal - try a vCard
00515   KABC::VCardConverter converter;
00516   return QString::fromUtf8( converter.createVCard( addressee ) );
00517 }
00518 
00519 QString KTnef::formatTNEFInvitation( const QByteArray &tnef,
00520                                      KCal::Calendar *cal,
00521                                      KCal::InvitationFormatterHelper *h )
00522 {
00523   QString vPart = msTNEFToVPart( tnef );
00524   QString iCal = IncidenceFormatter::formatICalInvitation( vPart, cal, h );
00525   if ( !iCal.isEmpty() ) {
00526     return iCal;
00527   } else {
00528     return vPart;
00529   }
00530 }
00531 

KTNEF Library

Skip menu "KTNEF Library"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal