mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 10:22:50 +00:00
563 lines
21 KiB
C++
563 lines
21 KiB
C++
/*
|
|
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
|
|
Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
|
|
Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
/**
|
|
@file
|
|
This file is part of the API for handling TNEF data and provides
|
|
static Formatter helpers.
|
|
|
|
@brief
|
|
Provides helpers too format @acronym TNEF attachments into different
|
|
formats like eg. a HTML representation.
|
|
|
|
@author Cornelius Schumacher
|
|
@author Reinhold Kainhofer
|
|
@author Rafal Rzepecki
|
|
*/
|
|
|
|
#include "formatter.h"
|
|
#include "ktnefparser.h"
|
|
#include "ktnefmessage.h"
|
|
#include "ktnefdefs.h"
|
|
|
|
#include <kpimutils/email.h>
|
|
#include <kabc/phonenumber.h>
|
|
#include <kabc/vcardconverter.h>
|
|
|
|
#ifndef KDEPIM_NO_KCAL
|
|
#include <kcal/incidenceformatter.h>
|
|
#include <kcal/calendar.h>
|
|
#endif
|
|
|
|
#include <kcalcore/calendar.h>
|
|
#include <kcalcore/icalformat.h>
|
|
#include <kcalutils/incidenceformatter.h>
|
|
|
|
#include <klocalizedstring.h>
|
|
#include <kdatetime.h>
|
|
|
|
#include <QtCore/QBuffer>
|
|
|
|
#include <time.h>
|
|
|
|
using namespace KCalCore;
|
|
using namespace KTnef;
|
|
|
|
/*******************************************************************
|
|
* Helper functions for the msTNEF -> VPart converter
|
|
*******************************************************************/
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//@cond IGNORE
|
|
static QString stringProp( KTNEFMessage *tnefMsg, const quint32 &key,
|
|
const QString &fallback = QString() )
|
|
{
|
|
return tnefMsg->findProp( key < 0x10000 ? key & 0xFFFF : key >> 16, fallback );
|
|
}
|
|
|
|
static QString sNamedProp( KTNEFMessage *tnefMsg, const QString &name,
|
|
const QString &fallback = QString() )
|
|
{
|
|
return tnefMsg->findNamedProp( name, fallback );
|
|
}
|
|
|
|
struct save_tz {
|
|
char *old_tz;
|
|
char *tz_env_str;
|
|
};
|
|
|
|
/* temporarily go to a different timezone */
|
|
static struct save_tz set_tz( const char *_tc )
|
|
{
|
|
const char *tc = _tc?_tc:"UTC";
|
|
|
|
struct save_tz rv;
|
|
|
|
rv.old_tz = 0;
|
|
rv.tz_env_str = 0;
|
|
|
|
//kDebug() << "set_tz(), timezone before =" << timezone;
|
|
|
|
char *tz_env = 0;
|
|
if ( !qgetenv( "TZ" ).isEmpty() ) {
|
|
tz_env = qstrdup( qgetenv( "TZ" ) );
|
|
rv.old_tz = tz_env;
|
|
}
|
|
char *tmp_env = (char*)malloc( strlen( tc ) + 4 );
|
|
strcpy( tmp_env, "TZ=" );
|
|
strcpy( tmp_env+3, tc );
|
|
putenv( tmp_env );
|
|
|
|
rv.tz_env_str = tmp_env;
|
|
|
|
/* tmp_env is not free'ed -- it is part of the environment */
|
|
|
|
tzset();
|
|
//kDebug() << "set_tz(), timezone after =" << timezone;
|
|
|
|
return rv;
|
|
}
|
|
|
|
/* restore previous timezone */
|
|
static void unset_tz( struct save_tz old_tz )
|
|
{
|
|
if ( old_tz.old_tz ) {
|
|
char *tmp_env = (char*)malloc( strlen( old_tz.old_tz ) + 4 );
|
|
strcpy( tmp_env, "TZ=" );
|
|
strcpy( tmp_env+3, old_tz.old_tz );
|
|
putenv( tmp_env );
|
|
/* tmp_env is not free'ed -- it is part of the environment */
|
|
free( old_tz.old_tz );
|
|
} else {
|
|
/* clear TZ from env */
|
|
putenv( strdup( "TZ" ) );
|
|
}
|
|
tzset();
|
|
|
|
/* is this OK? */
|
|
if ( old_tz.tz_env_str ) {
|
|
free( old_tz.tz_env_str );
|
|
}
|
|
}
|
|
|
|
static KDateTime utc2Local( const KDateTime &utcdt )
|
|
{
|
|
struct tm tmL;
|
|
|
|
save_tz tmp_tz = set_tz( "UTC" );
|
|
time_t utc = utcdt.toTime_t();
|
|
unset_tz( tmp_tz );
|
|
|
|
localtime_r( &utc, &tmL );
|
|
return KDateTime( QDate( tmL.tm_year + 1900, tmL.tm_mon + 1, tmL.tm_mday ),
|
|
QTime( tmL.tm_hour, tmL.tm_min, tmL.tm_sec ) );
|
|
}
|
|
|
|
static KDateTime pureISOToLocalQDateTime( const QString &dtStr,
|
|
bool bDateOnly = false )
|
|
{
|
|
QDate tmpDate;
|
|
QTime tmpTime;
|
|
int year, month, day, hour, minute, second;
|
|
|
|
if ( bDateOnly ) {
|
|
year = dtStr.left( 4 ).toInt();
|
|
month = dtStr.mid( 4, 2 ).toInt();
|
|
day = dtStr.mid( 6, 2 ).toInt();
|
|
hour = 0;
|
|
minute = 0;
|
|
second = 0;
|
|
} else {
|
|
year = dtStr.left( 4 ).toInt();
|
|
month = dtStr.mid( 4, 2 ).toInt();
|
|
day = dtStr.mid( 6, 2 ).toInt();
|
|
hour = dtStr.mid( 9, 2 ).toInt();
|
|
minute = dtStr.mid( 11, 2 ).toInt();
|
|
second = dtStr.mid( 13, 2 ).toInt();
|
|
}
|
|
tmpDate.setYMD( year, month, day );
|
|
tmpTime.setHMS( hour, minute, second );
|
|
|
|
if ( tmpDate.isValid() && tmpTime.isValid() ) {
|
|
KDateTime dT = KDateTime( tmpDate, tmpTime );
|
|
|
|
if ( !bDateOnly ) {
|
|
// correct for GMT ( == Zulu time == UTC )
|
|
if ( dtStr.at( dtStr.length() - 1 ) == 'Z' ) {
|
|
//dT = dT.addSecs( 60 * KRFCDate::localUTCOffset() );
|
|
//localUTCOffset( dT ) );
|
|
dT = utc2Local( dT );
|
|
}
|
|
}
|
|
return dT;
|
|
} else {
|
|
return KDateTime();
|
|
}
|
|
}
|
|
//@endcond
|
|
|
|
QString KTnef::msTNEFToVPart( const QByteArray &tnef )
|
|
{
|
|
bool bOk = false;
|
|
|
|
KTNEFParser parser;
|
|
QByteArray b( tnef );
|
|
QBuffer buf( &b );
|
|
MemoryCalendar::Ptr cal( new MemoryCalendar( KDateTime::UTC ) );
|
|
KABC::Addressee addressee;
|
|
ICalFormat calFormat;
|
|
Event::Ptr event( new Event() );
|
|
|
|
if ( parser.openDevice( &buf ) ) {
|
|
KTNEFMessage *tnefMsg = parser.message();
|
|
//QMap<int,KTNEFProperty*> props = parser.message()->properties();
|
|
|
|
// Everything depends from property PR_MESSAGE_CLASS
|
|
// (this is added by KTNEFParser):
|
|
QString msgClass = tnefMsg->findProp( 0x001A, QString(), true ).toUpper();
|
|
if ( !msgClass.isEmpty() ) {
|
|
// Match the old class names that might be used by Outlook for
|
|
// compatibility with Microsoft Mail for Windows for Workgroups 3.1.
|
|
bool bCompatClassAppointment = false;
|
|
bool bCompatMethodRequest = false;
|
|
bool bCompatMethodCancled = false;
|
|
bool bCompatMethodAccepted = false;
|
|
bool bCompatMethodAcceptedCond = false;
|
|
bool bCompatMethodDeclined = false;
|
|
if ( msgClass.startsWith( QLatin1String( "IPM.MICROSOFT SCHEDULE." ) ) ) {
|
|
bCompatClassAppointment = true;
|
|
if ( msgClass.endsWith( QLatin1String( ".MTGREQ" ) ) ) {
|
|
bCompatMethodRequest = true;
|
|
}
|
|
if ( msgClass.endsWith( QLatin1String( ".MTGCNCL" ) ) ) {
|
|
bCompatMethodCancled = true;
|
|
}
|
|
if ( msgClass.endsWith( QLatin1String( ".MTGRESPP" ) ) ) {
|
|
bCompatMethodAccepted = true;
|
|
}
|
|
if ( msgClass.endsWith( QLatin1String( ".MTGRESPA" ) ) ) {
|
|
bCompatMethodAcceptedCond = true;
|
|
}
|
|
if ( msgClass.endsWith( QLatin1String( ".MTGRESPN" ) ) ) {
|
|
bCompatMethodDeclined = true;
|
|
}
|
|
}
|
|
bool bCompatClassNote = ( msgClass == "IPM.MICROSOFT MAIL.NOTE" );
|
|
|
|
if ( bCompatClassAppointment || "IPM.APPOINTMENT" == msgClass ) {
|
|
// Compose a vCal
|
|
bool bIsReply = false;
|
|
QString prodID = "-//Microsoft Corporation//Outlook ";
|
|
prodID += tnefMsg->findNamedProp( "0x8554", "9.0" );
|
|
prodID += "MIMEDIR/EN\n";
|
|
prodID += "VERSION:2.0\n";
|
|
calFormat.setApplication( "Outlook", prodID );
|
|
|
|
iTIPMethod method;
|
|
if ( bCompatMethodRequest ) {
|
|
method = iTIPRequest;
|
|
} else if ( bCompatMethodCancled ) {
|
|
method = iTIPCancel;
|
|
} else if ( bCompatMethodAccepted || bCompatMethodAcceptedCond ||
|
|
bCompatMethodDeclined ) {
|
|
method = iTIPReply;
|
|
bIsReply = true;
|
|
} else {
|
|
// pending(khz): verify whether "0x0c17" is the right tag ???
|
|
//
|
|
// at the moment we think there are REQUESTS and UPDATES
|
|
//
|
|
// but WHAT ABOUT REPLIES ???
|
|
//
|
|
//
|
|
|
|
if ( tnefMsg->findProp(0x0c17) == "1" ) {
|
|
bIsReply = true;
|
|
}
|
|
method = iTIPRequest;
|
|
}
|
|
|
|
/// ### FIXME Need to get this attribute written
|
|
ScheduleMessage schedMsg( event, method, ScheduleMessage::Unknown );
|
|
|
|
QString sSenderSearchKeyEmail( tnefMsg->findProp( 0x0C1D ) );
|
|
|
|
if ( !sSenderSearchKeyEmail.isEmpty() ) {
|
|
int colon = sSenderSearchKeyEmail.indexOf( ':' );
|
|
// May be e.g. "SMTP:KHZ@KDE.ORG"
|
|
if ( sSenderSearchKeyEmail.indexOf( ':' ) == -1 ) {
|
|
sSenderSearchKeyEmail.remove( 0, colon+1 );
|
|
}
|
|
}
|
|
|
|
QString s( tnefMsg->findProp( 0x8189 ) );
|
|
const QStringList attendees = s.split( ';' );
|
|
if ( attendees.count() ) {
|
|
for ( QStringList::const_iterator it = attendees.begin();
|
|
it != attendees.end(); ++it ) {
|
|
// Skip all entries that have no '@' since these are
|
|
// no mail addresses
|
|
if ( (*it).indexOf( '@' ) == -1 ) {
|
|
s = (*it).trimmed();
|
|
|
|
Attendee::Ptr attendee( new Attendee( s, s, true ) );
|
|
if ( bIsReply ) {
|
|
if ( bCompatMethodAccepted ) {
|
|
attendee->setStatus( Attendee::Accepted );
|
|
}
|
|
if ( bCompatMethodDeclined ) {
|
|
attendee->setStatus( Attendee::Declined );
|
|
}
|
|
if ( bCompatMethodAcceptedCond ) {
|
|
attendee->setStatus( Attendee::Tentative );
|
|
}
|
|
} else {
|
|
attendee->setStatus( Attendee::NeedsAction );
|
|
attendee->setRole( Attendee::ReqParticipant );
|
|
}
|
|
event->addAttendee( attendee );
|
|
}
|
|
}
|
|
} else {
|
|
// Oops, no attendees?
|
|
// This must be old style, let us use the PR_SENDER_SEARCH_KEY.
|
|
s = sSenderSearchKeyEmail;
|
|
if ( !s.isEmpty() ) {
|
|
Attendee::Ptr attendee( new Attendee( QString(), QString(), true ) );
|
|
if ( bIsReply ) {
|
|
if ( bCompatMethodAccepted ) {
|
|
attendee->setStatus( Attendee::Accepted );
|
|
}
|
|
if ( bCompatMethodAcceptedCond ) {
|
|
attendee->setStatus( Attendee::Declined );
|
|
}
|
|
if ( bCompatMethodDeclined ) {
|
|
attendee->setStatus( Attendee::Tentative );
|
|
}
|
|
} else {
|
|
attendee->setStatus( Attendee::NeedsAction );
|
|
attendee->setRole( Attendee::ReqParticipant );
|
|
}
|
|
event->addAttendee( attendee );
|
|
}
|
|
}
|
|
s = tnefMsg->findProp( 0x3ff8 ); // look for organizer property
|
|
if ( s.isEmpty() && !bIsReply ) {
|
|
s = sSenderSearchKeyEmail;
|
|
}
|
|
// TODO: Use the common name?
|
|
if ( !s.isEmpty() ) {
|
|
event->setOrganizer( s );
|
|
}
|
|
|
|
s = tnefMsg->findProp( 0x819b ).remove( QChar( '-' ) ).remove( QChar( ':' ) );
|
|
event->setDtStart( KDateTime::fromString( s ) ); // ## Format??
|
|
|
|
s = tnefMsg->findProp( 0x819c ).remove( QChar( '-' ) ).remove( QChar( ':' ) );
|
|
event->setDtEnd( KDateTime::fromString( s ) );
|
|
|
|
s = tnefMsg->findProp( 0x810d );
|
|
event->setLocation( s );
|
|
// is it OK to set this to OPAQUE always ??
|
|
//vPart += "TRANSP:OPAQUE\n"; ###FIXME, portme!
|
|
//vPart += "SEQUENCE:0\n";
|
|
|
|
// is "0x0023" OK - or should we look for "0x0003" ??
|
|
s = tnefMsg->findProp( 0x0023 );
|
|
event->setUid( s );
|
|
|
|
// PENDING(khz): is this value in local timezone? Must it be
|
|
// adjusted? Most likely this is a bug in the server or in
|
|
// Outlook - we ignore it for now.
|
|
s = tnefMsg->findProp( 0x8202 ).remove( QChar( '-' ) ).remove( QChar( ':' ) );
|
|
// ### kcal always uses currentDateTime()
|
|
// event->setDtStamp( QDateTime::fromString( s ) );
|
|
|
|
s = tnefMsg->findNamedProp( "Keywords" );
|
|
event->setCategories( s );
|
|
|
|
s = tnefMsg->findProp( 0x1000 );
|
|
event->setDescription( s );
|
|
|
|
s = tnefMsg->findProp( 0x0070 );
|
|
event->setSummary( s );
|
|
|
|
s = tnefMsg->findProp( 0x0026 );
|
|
event->setPriority( s.toInt() );
|
|
// is reminder flag set ?
|
|
if ( !tnefMsg->findProp( 0x8503 ).isEmpty() ) {
|
|
Alarm::Ptr alarm( new Alarm( event.data() ) ); // TODO: fix when KCalCore::Alarm is fixed
|
|
KDateTime highNoonTime =
|
|
pureISOToLocalQDateTime( tnefMsg->findProp( 0x8502 ).
|
|
remove( QChar( '-' ) ).remove( QChar( ':' ) ) );
|
|
KDateTime wakeMeUpTime =
|
|
pureISOToLocalQDateTime( tnefMsg->findProp( 0x8560, "" ).
|
|
remove( QChar( '-' ) ).remove( QChar( ':' ) ) );
|
|
alarm->setTime( wakeMeUpTime );
|
|
|
|
if ( highNoonTime.isValid() && wakeMeUpTime.isValid() ) {
|
|
alarm->setStartOffset( Duration( highNoonTime, wakeMeUpTime ) );
|
|
} else {
|
|
// default: wake them up 15 minutes before the appointment
|
|
alarm->setStartOffset( Duration( 15 * 60 ) );
|
|
}
|
|
alarm->setDisplayAlarm( i18n( "Reminder" ) );
|
|
|
|
// Sorry: the different action types are not known (yet)
|
|
// so we always set 'DISPLAY' (no sounds, no images...)
|
|
event->addAlarm( alarm );
|
|
}
|
|
//ensure we have a uid for this event
|
|
if ( event->uid().isEmpty() ) {
|
|
event->setUid( CalFormat::createUniqueId() );
|
|
}
|
|
cal->addEvent( event );
|
|
bOk = true;
|
|
// we finished composing a vCal
|
|
} else if ( bCompatClassNote || "IPM.CONTACT" == msgClass ) {
|
|
addressee.setUid( stringProp( tnefMsg, attMSGID ) );
|
|
addressee.setFormattedName( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME ) );
|
|
addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL1EMAILADDRESS ), true );
|
|
addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL2EMAILADDRESS ), false );
|
|
addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL3EMAILADDRESS ), false );
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-IMAddress",
|
|
sNamedProp( tnefMsg, MAPI_TAG_CONTACT_IMADDRESS ) );
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-SpousesName",
|
|
stringProp( tnefMsg, MAPI_TAG_PR_SPOUSE_NAME ) );
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-ManagersName",
|
|
stringProp( tnefMsg, MAPI_TAG_PR_MANAGER_NAME ) );
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-AssistantsName",
|
|
stringProp( tnefMsg, MAPI_TAG_PR_ASSISTANT ) );
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-Department",
|
|
stringProp( tnefMsg, MAPI_TAG_PR_DEPARTMENT_NAME ) );
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-Office",
|
|
stringProp( tnefMsg, MAPI_TAG_PR_OFFICE_LOCATION ) );
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-Profession",
|
|
stringProp( tnefMsg, MAPI_TAG_PR_PROFESSION ) );
|
|
|
|
QString s = tnefMsg->findProp( MAPI_TAG_PR_WEDDING_ANNIVERSARY ).
|
|
remove( QChar( '-' ) ).remove( QChar( ':' ) );
|
|
if ( !s.isEmpty() ) {
|
|
addressee.insertCustom( "KADDRESSBOOK", "X-Anniversary", s );
|
|
}
|
|
|
|
addressee.setUrl( KUrl( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_WEBPAGE ) ) );
|
|
|
|
// collect parts of Name entry
|
|
addressee.setFamilyName( stringProp( tnefMsg, MAPI_TAG_PR_SURNAME ) );
|
|
addressee.setGivenName( stringProp( tnefMsg, MAPI_TAG_PR_GIVEN_NAME ) );
|
|
addressee.setAdditionalName( stringProp( tnefMsg, MAPI_TAG_PR_MIDDLE_NAME ) );
|
|
addressee.setPrefix( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME_PREFIX ) );
|
|
addressee.setSuffix( stringProp( tnefMsg, MAPI_TAG_PR_GENERATION ) );
|
|
|
|
addressee.setNickName( stringProp( tnefMsg, MAPI_TAG_PR_NICKNAME ) );
|
|
addressee.setRole( stringProp( tnefMsg, MAPI_TAG_PR_TITLE ) );
|
|
addressee.setOrganization( stringProp( tnefMsg, MAPI_TAG_PR_COMPANY_NAME ) );
|
|
/*
|
|
the MAPI property ID of this (multiline) )field is unknown:
|
|
vPart += stringProp(tnefMsg, "\n","NOTE", ... , "" );
|
|
*/
|
|
|
|
KABC::Address adr;
|
|
adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_PO_BOX ) );
|
|
adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STREET ) );
|
|
adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_CITY ) );
|
|
adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STATE_OR_PROVINCE ) );
|
|
adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_POSTAL_CODE ) );
|
|
adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_COUNTRY ) );
|
|
adr.setType( KABC::Address::Home );
|
|
addressee.insertAddress( adr );
|
|
|
|
adr.setPostOfficeBox( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOBOX ) );
|
|
adr.setStreet( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTREET ) );
|
|
adr.setLocality( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCITY ) );
|
|
adr.setRegion( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTATE ) );
|
|
adr.setPostalCode( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOSTALCODE ) );
|
|
adr.setCountry( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCOUNTRY ) );
|
|
adr.setType( KABC::Address::Work );
|
|
addressee.insertAddress( adr );
|
|
|
|
adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_PO_BOX ) );
|
|
adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STREET ) );
|
|
adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_CITY ) );
|
|
adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STATE_OR_PROVINCE ) );
|
|
adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_POSTAL_CODE ) );
|
|
adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_COUNTRY ) );
|
|
adr.setType( KABC::Address::Dom );
|
|
addressee.insertAddress( adr );
|
|
|
|
// problem: the 'other' address was stored by KOrganizer in
|
|
// a line looking like the following one:
|
|
// 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"
|
|
|
|
QString nr;
|
|
nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_TELEPHONE_NUMBER );
|
|
addressee.insertPhoneNumber(
|
|
KABC::PhoneNumber( nr, KABC::PhoneNumber::Home ) );
|
|
nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_TELEPHONE_NUMBER );
|
|
addressee.insertPhoneNumber(
|
|
KABC::PhoneNumber( nr, KABC::PhoneNumber::Work ) );
|
|
nr = stringProp( tnefMsg, MAPI_TAG_PR_MOBILE_TELEPHONE_NUMBER );
|
|
addressee.insertPhoneNumber(
|
|
KABC::PhoneNumber( nr, KABC::PhoneNumber::Cell ) );
|
|
nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_FAX_NUMBER );
|
|
addressee.insertPhoneNumber(
|
|
KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ) );
|
|
nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_FAX_NUMBER );
|
|
addressee.insertPhoneNumber(
|
|
KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work ) );
|
|
|
|
s = tnefMsg->findProp( MAPI_TAG_PR_BIRTHDAY ).
|
|
remove( QChar( '-' ) ).remove( QChar( ':' ) );
|
|
if ( !s.isEmpty() ) {
|
|
addressee.setBirthday( QDateTime::fromString( s ) );
|
|
}
|
|
|
|
bOk = ( !addressee.isEmpty() );
|
|
} else if ( "IPM.NOTE" == msgClass ) {
|
|
|
|
} // else if ... and so on ...
|
|
}
|
|
}
|
|
|
|
// Compose return string
|
|
// KDAB_TODO: Interesting, without the explicit QString the toString call is
|
|
// reported to be ambigious with toString( const Incidence::Ptr & ).
|
|
const QString iCal = calFormat.toString( cal, QString() );
|
|
if ( !iCal.isEmpty() ) {
|
|
// This was an iCal
|
|
return iCal;
|
|
}
|
|
|
|
// Not an iCal - try a vCard
|
|
KABC::VCardConverter converter;
|
|
return QString::fromUtf8( converter.createVCard( addressee ) );
|
|
}
|
|
|
|
#ifndef KDEPIM_NO_KCAL
|
|
QString KTnef::formatTNEFInvitation( const QByteArray &tnef,
|
|
KCal::Calendar *cal,
|
|
KCal::InvitationFormatterHelper *h )
|
|
{
|
|
QString vPart = msTNEFToVPart( tnef );
|
|
QString iCal = KCal::IncidenceFormatter::formatICalInvitation( vPart, cal, h );
|
|
if ( !iCal.isEmpty() ) {
|
|
return iCal;
|
|
} else {
|
|
return vPart;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
QString KTnef::formatTNEFInvitation( const QByteArray &tnef,
|
|
const MemoryCalendar::Ptr &cal,
|
|
KCalUtils::InvitationFormatterHelper *h )
|
|
{
|
|
const QString vPart = msTNEFToVPart( tnef );
|
|
QString iCal = KCalUtils::IncidenceFormatter::formatICalInvitation( vPart, cal, h, true );
|
|
if ( !iCal.isEmpty() ) {
|
|
return iCal;
|
|
} else {
|
|
return vPart;
|
|
}
|
|
}
|
|
|