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

KTNEF Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • 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.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