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

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