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

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"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.1
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