libkcal Library API Documentation

incidenceformatter.cpp

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