• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

KTNEF Library

  • ktnef
formatter.cpp
Go to the documentation of this file.
1/*
2 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
3 Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
4 Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
35#include "formatter.h"
36#include "ktnefparser.h"
37#include "ktnefmessage.h"
38#include "ktnefdefs.h"
39
40#include <kpimutils/email.h>
41#include <kabc/phonenumber.h>
42#include <kabc/vcardconverter.h>
43
44#ifndef KDEPIM_NO_KCAL
45#include <kcal/incidenceformatter.h>
46#include <kcal/calendar.h>
47#endif
48
49#include <kcalcore/calendar.h>
50#include <kcalcore/icalformat.h>
51#include <kcalutils/incidenceformatter.h>
52
53#include <klocalizedstring.h>
54#include <kdatetime.h>
55
56#include <QtCore/QBuffer>
57
58#include <time.h>
59
60using namespace KCalCore;
61using namespace KTnef;
62
63/*******************************************************************
64 * Helper functions for the msTNEF -> VPart converter
65 *******************************************************************/
66
67//-----------------------------------------------------------------------------
68//@cond IGNORE
69static QString stringProp( KTNEFMessage *tnefMsg, const quint32 &key,
70 const QString &fallback = QString() )
71{
72 return tnefMsg->findProp( key < 0x10000 ? key & 0xFFFF : key >> 16, fallback );
73}
74
75static QString sNamedProp( KTNEFMessage *tnefMsg, const QString &name,
76 const QString &fallback = QString() )
77{
78 return tnefMsg->findNamedProp( name, fallback );
79}
80
81struct save_tz {
82 char *old_tz;
83 char *tz_env_str;
84};
85
86/* temporarily go to a different timezone */
87static struct save_tz set_tz( const char *_tc )
88{
89 const char *tc = _tc?_tc:"UTC";
90
91 struct save_tz rv;
92
93 rv.old_tz = 0;
94 rv.tz_env_str = 0;
95
96 //kDebug() << "set_tz(), timezone before =" << timezone;
97
98 char *tz_env = 0;
99 if ( !qgetenv( "TZ" ).isEmpty() ) {
100 tz_env = qstrdup( qgetenv( "TZ" ) );
101 rv.old_tz = tz_env;
102 }
103 char *tmp_env = (char*)malloc( strlen( tc ) + 4 );
104 strcpy( tmp_env, "TZ=" );
105 strcpy( tmp_env+3, tc );
106 putenv( tmp_env );
107
108 rv.tz_env_str = tmp_env;
109
110 /* tmp_env is not free'ed -- it is part of the environment */
111
112 tzset();
113 //kDebug() << "set_tz(), timezone after =" << timezone;
114
115 return rv;
116}
117
118/* restore previous timezone */
119static void unset_tz( struct save_tz old_tz )
120{
121 if ( old_tz.old_tz ) {
122 char *tmp_env = (char*)malloc( strlen( old_tz.old_tz ) + 4 );
123 strcpy( tmp_env, "TZ=" );
124 strcpy( tmp_env+3, old_tz.old_tz );
125 putenv( tmp_env );
126 /* tmp_env is not free'ed -- it is part of the environment */
127 free( old_tz.old_tz );
128 } else {
129 /* clear TZ from env */
130 putenv( strdup( "TZ" ) );
131 }
132 tzset();
133
134 /* is this OK? */
135 if ( old_tz.tz_env_str ) {
136 free( old_tz.tz_env_str );
137 }
138}
139
140static KDateTime utc2Local( const KDateTime &utcdt )
141{
142 struct tm tmL;
143
144 save_tz tmp_tz = set_tz( "UTC" );
145 time_t utc = utcdt.toTime_t();
146 unset_tz( tmp_tz );
147
148 localtime_r( &utc, &tmL );
149 return KDateTime( QDate( tmL.tm_year + 1900, tmL.tm_mon + 1, tmL.tm_mday ),
150 QTime( tmL.tm_hour, tmL.tm_min, tmL.tm_sec ) );
151}
152
153static KDateTime pureISOToLocalQDateTime( const QString &dtStr,
154 bool bDateOnly = false )
155{
156 QDate tmpDate;
157 QTime tmpTime;
158 int year, month, day, hour, minute, second;
159
160 if ( bDateOnly ) {
161 year = dtStr.left( 4 ).toInt();
162 month = dtStr.mid( 4, 2 ).toInt();
163 day = dtStr.mid( 6, 2 ).toInt();
164 hour = 0;
165 minute = 0;
166 second = 0;
167 } else {
168 year = dtStr.left( 4 ).toInt();
169 month = dtStr.mid( 4, 2 ).toInt();
170 day = dtStr.mid( 6, 2 ).toInt();
171 hour = dtStr.mid( 9, 2 ).toInt();
172 minute = dtStr.mid( 11, 2 ).toInt();
173 second = dtStr.mid( 13, 2 ).toInt();
174 }
175 tmpDate.setYMD( year, month, day );
176 tmpTime.setHMS( hour, minute, second );
177
178 if ( tmpDate.isValid() && tmpTime.isValid() ) {
179 KDateTime dT = KDateTime( tmpDate, tmpTime );
180
181 if ( !bDateOnly ) {
182 // correct for GMT ( == Zulu time == UTC )
183 if ( dtStr.at( dtStr.length() - 1 ) == 'Z' ) {
184 //dT = dT.addSecs( 60 * KRFCDate::localUTCOffset() );
185 //localUTCOffset( dT ) );
186 dT = utc2Local( dT );
187 }
188 }
189 return dT;
190 } else {
191 return KDateTime();
192 }
193}
194//@endcond
195
196QString KTnef::msTNEFToVPart( const QByteArray &tnef )
197{
198 bool bOk = false;
199
200 KTNEFParser parser;
201 QByteArray b( tnef );
202 QBuffer buf( &b );
203 MemoryCalendar::Ptr cal( new MemoryCalendar( KDateTime::UTC ) );
204 KABC::Addressee addressee;
205 ICalFormat calFormat;
206 Event::Ptr event( new Event() );
207
208 if ( parser.openDevice( &buf ) ) {
209 KTNEFMessage *tnefMsg = parser.message();
210 //QMap<int,KTNEFProperty*> props = parser.message()->properties();
211
212 // Everything depends from property PR_MESSAGE_CLASS
213 // (this is added by KTNEFParser):
214 QString msgClass = tnefMsg->findProp( 0x001A, QString(), true ).toUpper();
215 if ( !msgClass.isEmpty() ) {
216 // Match the old class names that might be used by Outlook for
217 // compatibility with Microsoft Mail for Windows for Workgroups 3.1.
218 bool bCompatClassAppointment = false;
219 bool bCompatMethodRequest = false;
220 bool bCompatMethodCancled = false;
221 bool bCompatMethodAccepted = false;
222 bool bCompatMethodAcceptedCond = false;
223 bool bCompatMethodDeclined = false;
224 if ( msgClass.startsWith( QLatin1String( "IPM.MICROSOFT SCHEDULE." ) ) ) {
225 bCompatClassAppointment = true;
226 if ( msgClass.endsWith( QLatin1String( ".MTGREQ" ) ) ) {
227 bCompatMethodRequest = true;
228 }
229 if ( msgClass.endsWith( QLatin1String( ".MTGCNCL" ) ) ) {
230 bCompatMethodCancled = true;
231 }
232 if ( msgClass.endsWith( QLatin1String( ".MTGRESPP" ) ) ) {
233 bCompatMethodAccepted = true;
234 }
235 if ( msgClass.endsWith( QLatin1String( ".MTGRESPA" ) ) ) {
236 bCompatMethodAcceptedCond = true;
237 }
238 if ( msgClass.endsWith( QLatin1String( ".MTGRESPN" ) ) ) {
239 bCompatMethodDeclined = true;
240 }
241 }
242 bool bCompatClassNote = ( msgClass == "IPM.MICROSOFT MAIL.NOTE" );
243
244 if ( bCompatClassAppointment || "IPM.APPOINTMENT" == msgClass ) {
245 // Compose a vCal
246 bool bIsReply = false;
247 QString prodID = "-//Microsoft Corporation//Outlook ";
248 prodID += tnefMsg->findNamedProp( "0x8554", "9.0" );
249 prodID += "MIMEDIR/EN\n";
250 prodID += "VERSION:2.0\n";
251 calFormat.setApplication( "Outlook", prodID );
252
253 iTIPMethod method;
254 if ( bCompatMethodRequest ) {
255 method = iTIPRequest;
256 } else if ( bCompatMethodCancled ) {
257 method = iTIPCancel;
258 } else if ( bCompatMethodAccepted || bCompatMethodAcceptedCond ||
259 bCompatMethodDeclined ) {
260 method = iTIPReply;
261 bIsReply = true;
262 } else {
263 // pending(khz): verify whether "0x0c17" is the right tag ???
264 //
265 // at the moment we think there are REQUESTS and UPDATES
266 //
267 // but WHAT ABOUT REPLIES ???
268 //
269 //
270
271 if ( tnefMsg->findProp(0x0c17) == "1" ) {
272 bIsReply = true;
273 }
274 method = iTIPRequest;
275 }
276
278 ScheduleMessage schedMsg( event, method, ScheduleMessage::Unknown );
279
280 QString sSenderSearchKeyEmail( tnefMsg->findProp( 0x0C1D ) );
281
282 if ( !sSenderSearchKeyEmail.isEmpty() ) {
283 int colon = sSenderSearchKeyEmail.indexOf( ':' );
284 // May be e.g. "SMTP:KHZ@KDE.ORG"
285 if ( sSenderSearchKeyEmail.indexOf( ':' ) == -1 ) {
286 sSenderSearchKeyEmail.remove( 0, colon+1 );
287 }
288 }
289
290 QString s( tnefMsg->findProp( 0x8189 ) );
291 const QStringList attendees = s.split( ';' );
292 if ( attendees.count() ) {
293 for ( QStringList::const_iterator it = attendees.begin();
294 it != attendees.end(); ++it ) {
295 // Skip all entries that have no '@' since these are
296 // no mail addresses
297 if ( (*it).indexOf( '@' ) == -1 ) {
298 s = (*it).trimmed();
299
300 Attendee::Ptr attendee( new Attendee( s, s, true ) );
301 if ( bIsReply ) {
302 if ( bCompatMethodAccepted ) {
303 attendee->setStatus( Attendee::Accepted );
304 }
305 if ( bCompatMethodDeclined ) {
306 attendee->setStatus( Attendee::Declined );
307 }
308 if ( bCompatMethodAcceptedCond ) {
309 attendee->setStatus( Attendee::Tentative );
310 }
311 } else {
312 attendee->setStatus( Attendee::NeedsAction );
313 attendee->setRole( Attendee::ReqParticipant );
314 }
315 event->addAttendee( attendee );
316 }
317 }
318 } else {
319 // Oops, no attendees?
320 // This must be old style, let us use the PR_SENDER_SEARCH_KEY.
321 s = sSenderSearchKeyEmail;
322 if ( !s.isEmpty() ) {
323 Attendee::Ptr attendee( new Attendee( QString(), QString(), true ) );
324 if ( bIsReply ) {
325 if ( bCompatMethodAccepted ) {
326 attendee->setStatus( Attendee::Accepted );
327 }
328 if ( bCompatMethodAcceptedCond ) {
329 attendee->setStatus( Attendee::Declined );
330 }
331 if ( bCompatMethodDeclined ) {
332 attendee->setStatus( Attendee::Tentative );
333 }
334 } else {
335 attendee->setStatus( Attendee::NeedsAction );
336 attendee->setRole( Attendee::ReqParticipant );
337 }
338 event->addAttendee( attendee );
339 }
340 }
341 s = tnefMsg->findProp( 0x3ff8 ); // look for organizer property
342 if ( s.isEmpty() && !bIsReply ) {
343 s = sSenderSearchKeyEmail;
344 }
345 // TODO: Use the common name?
346 if ( !s.isEmpty() ) {
347 event->setOrganizer( s );
348 }
349
350 s = tnefMsg->findProp( 0x819b ).remove( QChar( '-' ) ).remove( QChar( ':' ) );
351 event->setDtStart( KDateTime::fromString( s ) ); // ## Format??
352
353 s = tnefMsg->findProp( 0x819c ).remove( QChar( '-' ) ).remove( QChar( ':' ) );
354 event->setDtEnd( KDateTime::fromString( s ) );
355
356 s = tnefMsg->findProp( 0x810d );
357 event->setLocation( s );
358 // is it OK to set this to OPAQUE always ??
359 //vPart += "TRANSP:OPAQUE\n"; ###FIXME, portme!
360 //vPart += "SEQUENCE:0\n";
361
362 // is "0x0023" OK - or should we look for "0x0003" ??
363 s = tnefMsg->findProp( 0x0023 );
364 event->setUid( s );
365
366 // PENDING(khz): is this value in local timezone? Must it be
367 // adjusted? Most likely this is a bug in the server or in
368 // Outlook - we ignore it for now.
369 s = tnefMsg->findProp( 0x8202 ).remove( QChar( '-' ) ).remove( QChar( ':' ) );
370 // ### kcal always uses currentDateTime()
371 // event->setDtStamp( QDateTime::fromString( s ) );
372
373 s = tnefMsg->findNamedProp( "Keywords" );
374 event->setCategories( s );
375
376 s = tnefMsg->findProp( 0x1000 );
377 event->setDescription( s );
378
379 s = tnefMsg->findProp( 0x0070 );
380 event->setSummary( s );
381
382 s = tnefMsg->findProp( 0x0026 );
383 event->setPriority( s.toInt() );
384 // is reminder flag set ?
385 if ( !tnefMsg->findProp( 0x8503 ).isEmpty() ) {
386 Alarm::Ptr alarm( new Alarm( event.data() ) ); // TODO: fix when KCalCore::Alarm is fixed
387 KDateTime highNoonTime =
388 pureISOToLocalQDateTime( tnefMsg->findProp( 0x8502 ).
389 remove( QChar( '-' ) ).remove( QChar( ':' ) ) );
390 KDateTime wakeMeUpTime =
391 pureISOToLocalQDateTime( tnefMsg->findProp( 0x8560, "" ).
392 remove( QChar( '-' ) ).remove( QChar( ':' ) ) );
393 alarm->setTime( wakeMeUpTime );
394
395 if ( highNoonTime.isValid() && wakeMeUpTime.isValid() ) {
396 alarm->setStartOffset( Duration( highNoonTime, wakeMeUpTime ) );
397 } else {
398 // default: wake them up 15 minutes before the appointment
399 alarm->setStartOffset( Duration( 15 * 60 ) );
400 }
401 alarm->setDisplayAlarm( i18n( "Reminder" ) );
402
403 // Sorry: the different action types are not known (yet)
404 // so we always set 'DISPLAY' (no sounds, no images...)
405 event->addAlarm( alarm );
406 }
407 //ensure we have a uid for this event
408 if ( event->uid().isEmpty() ) {
409 event->setUid( CalFormat::createUniqueId() );
410 }
411 cal->addEvent( event );
412 bOk = true;
413 // we finished composing a vCal
414 } else if ( bCompatClassNote || "IPM.CONTACT" == msgClass ) {
415 addressee.setUid( stringProp( tnefMsg, attMSGID ) );
416 addressee.setFormattedName( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME ) );
417 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL1EMAILADDRESS ), true );
418 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL2EMAILADDRESS ), false );
419 addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL3EMAILADDRESS ), false );
420 addressee.insertCustom( "KADDRESSBOOK", "X-IMAddress",
421 sNamedProp( tnefMsg, MAPI_TAG_CONTACT_IMADDRESS ) );
422 addressee.insertCustom( "KADDRESSBOOK", "X-SpousesName",
423 stringProp( tnefMsg, MAPI_TAG_PR_SPOUSE_NAME ) );
424 addressee.insertCustom( "KADDRESSBOOK", "X-ManagersName",
425 stringProp( tnefMsg, MAPI_TAG_PR_MANAGER_NAME ) );
426 addressee.insertCustom( "KADDRESSBOOK", "X-AssistantsName",
427 stringProp( tnefMsg, MAPI_TAG_PR_ASSISTANT ) );
428 addressee.insertCustom( "KADDRESSBOOK", "X-Department",
429 stringProp( tnefMsg, MAPI_TAG_PR_DEPARTMENT_NAME ) );
430 addressee.insertCustom( "KADDRESSBOOK", "X-Office",
431 stringProp( tnefMsg, MAPI_TAG_PR_OFFICE_LOCATION ) );
432 addressee.insertCustom( "KADDRESSBOOK", "X-Profession",
433 stringProp( tnefMsg, MAPI_TAG_PR_PROFESSION ) );
434
435 QString s = tnefMsg->findProp( MAPI_TAG_PR_WEDDING_ANNIVERSARY ).
436 remove( QChar( '-' ) ).remove( QChar( ':' ) );
437 if ( !s.isEmpty() ) {
438 addressee.insertCustom( "KADDRESSBOOK", "X-Anniversary", s );
439 }
440
441 addressee.setUrl( KUrl( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_WEBPAGE ) ) );
442
443 // collect parts of Name entry
444 addressee.setFamilyName( stringProp( tnefMsg, MAPI_TAG_PR_SURNAME ) );
445 addressee.setGivenName( stringProp( tnefMsg, MAPI_TAG_PR_GIVEN_NAME ) );
446 addressee.setAdditionalName( stringProp( tnefMsg, MAPI_TAG_PR_MIDDLE_NAME ) );
447 addressee.setPrefix( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME_PREFIX ) );
448 addressee.setSuffix( stringProp( tnefMsg, MAPI_TAG_PR_GENERATION ) );
449
450 addressee.setNickName( stringProp( tnefMsg, MAPI_TAG_PR_NICKNAME ) );
451 addressee.setRole( stringProp( tnefMsg, MAPI_TAG_PR_TITLE ) );
452 addressee.setOrganization( stringProp( tnefMsg, MAPI_TAG_PR_COMPANY_NAME ) );
453 /*
454 the MAPI property ID of this (multiline) )field is unknown:
455 vPart += stringProp(tnefMsg, "\n","NOTE", ... , "" );
456 */
457
458 KABC::Address adr;
459 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_PO_BOX ) );
460 adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STREET ) );
461 adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_CITY ) );
462 adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STATE_OR_PROVINCE ) );
463 adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_POSTAL_CODE ) );
464 adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_COUNTRY ) );
465 adr.setType( KABC::Address::Home );
466 addressee.insertAddress( adr );
467
468 adr.setPostOfficeBox( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOBOX ) );
469 adr.setStreet( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTREET ) );
470 adr.setLocality( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCITY ) );
471 adr.setRegion( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTATE ) );
472 adr.setPostalCode( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOSTALCODE ) );
473 adr.setCountry( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCOUNTRY ) );
474 adr.setType( KABC::Address::Work );
475 addressee.insertAddress( adr );
476
477 adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_PO_BOX ) );
478 adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STREET ) );
479 adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_CITY ) );
480 adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STATE_OR_PROVINCE ) );
481 adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_POSTAL_CODE ) );
482 adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_COUNTRY ) );
483 adr.setType( KABC::Address::Dom );
484 addressee.insertAddress( adr );
485
486 // problem: the 'other' address was stored by KOrganizer in
487 // a line looking like the following one:
488 // vPart += "\nADR;TYPE=dom;TYPE=intl;TYPE=parcel;TYPE=postal;TYPE=work;"
489 // "TYPE=home:other_pobox;;other_str1\nother_str2;other_loc;other_region;"
490 // "other_pocode;other_country"
491
492 QString nr;
493 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_TELEPHONE_NUMBER );
494 addressee.insertPhoneNumber(
495 KABC::PhoneNumber( nr, KABC::PhoneNumber::Home ) );
496 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_TELEPHONE_NUMBER );
497 addressee.insertPhoneNumber(
498 KABC::PhoneNumber( nr, KABC::PhoneNumber::Work ) );
499 nr = stringProp( tnefMsg, MAPI_TAG_PR_MOBILE_TELEPHONE_NUMBER );
500 addressee.insertPhoneNumber(
501 KABC::PhoneNumber( nr, KABC::PhoneNumber::Cell ) );
502 nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_FAX_NUMBER );
503 addressee.insertPhoneNumber(
504 KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ) );
505 nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_FAX_NUMBER );
506 addressee.insertPhoneNumber(
507 KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work ) );
508
509 s = tnefMsg->findProp( MAPI_TAG_PR_BIRTHDAY ).
510 remove( QChar( '-' ) ).remove( QChar( ':' ) );
511 if ( !s.isEmpty() ) {
512 addressee.setBirthday( QDateTime::fromString( s ) );
513 }
514
515 bOk = ( !addressee.isEmpty() );
516 } else if ( "IPM.NOTE" == msgClass ) {
517
518 } // else if ... and so on ...
519 }
520 }
521
522 // Compose return string
523 // KDAB_TODO: Interesting, without the explicit QString the toString call is
524 // reported to be ambigious with toString( const Incidence::Ptr & ).
525 const QString iCal = calFormat.toString( cal, QString() );
526 if ( !iCal.isEmpty() ) {
527 // This was an iCal
528 return iCal;
529 }
530
531 // Not an iCal - try a vCard
532 KABC::VCardConverter converter;
533 return QString::fromUtf8( converter.createVCard( addressee ) );
534}
535
536#ifndef KDEPIM_NO_KCAL
537QString KTnef::formatTNEFInvitation( const QByteArray &tnef,
538 KCal::Calendar *cal,
539 KCal::InvitationFormatterHelper *h )
540{
541 QString vPart = msTNEFToVPart( tnef );
542 QString iCal = KCal::IncidenceFormatter::formatICalInvitation( vPart, cal, h );
543 if ( !iCal.isEmpty() ) {
544 return iCal;
545 } else {
546 return vPart;
547 }
548}
549#endif
550
551QString KTnef::formatTNEFInvitation( const QByteArray &tnef,
552 const MemoryCalendar::Ptr &cal,
553 KCalUtils::InvitationFormatterHelper *h )
554{
555 const QString vPart = msTNEFToVPart( tnef );
556 QString iCal = KCalUtils::IncidenceFormatter::formatICalInvitation( vPart, cal, h, true );
557 if ( !iCal.isEmpty() ) {
558 return iCal;
559 } else {
560 return vPart;
561 }
562}
563
calendar.h
KCal::Calendar
KTnef::KTNEFMessage
Represents a TNEF message.
Definition ktnefmessage.h:50
KTnef::KTNEFParser
Provides an TNEF parser.
Definition ktnefparser.h:52
KTnef::KTNEFParser::openDevice
bool openDevice(QIODevice *device)
Opens the #QIODevice device for parsing.
Definition ktnefparser.cpp:524
KTnef::KTNEFParser::message
KTNEFMessage * message() const
Returns the KTNEFMessage used in the parsing process.
Definition ktnefparser.cpp:127
KTnef::KTNEFPropertySet::findProp
QString findProp(int key, const QString &fallback=QString(), bool convertToUpper=false) const
Finds a property by key, returning a formatted value.
Definition ktnefpropertyset.cpp:74
KTnef::KTNEFPropertySet::findNamedProp
QString findNamedProp(const QString &name, const QString &fallback=QString(), bool convertToUpper=false) const
Finds a property by name, returning a formatted value.
Definition ktnefpropertyset.cpp:87
formatter.h
This file is part of the API for handling TNEF data and provides static Formatter helpers.
KTnef::msTNEFToVPart
QString msTNEFToVPart(const QByteArray &tnef)
Transforms a TNEF attachment to an iCal or vCard.
Definition formatter.cpp:196
KTnef::formatTNEFInvitation
KTNEF_DEPRECATED_EXPORT QString formatTNEFInvitation(const QByteArray &tnef, KCal::Calendar *cal, KCal::InvitationFormatterHelper *h)
Formats a TNEF attachment to an HTML mail.
Definition formatter.cpp:537
incidenceformatter.h
ktnefdefs.h
This file is part of the API for handling TNEF data and provides some basic definitions for general u...
ktnefmessage.h
This file is part of the API for handling TNEF data and defines the KTNEFMessage class.
ktnefparser.h
This file is part of the API for handling TNEF data and defines the KTNEFParser class.
KCal::IncidenceFormatter::formatICalInvitation
KCAL_DEPRECATED_EXPORT QString formatICalInvitation(QString invitation, Calendar *calendar, InvitationFormatterHelper *helper)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KTNEF Library

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

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal