• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.10.5 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 <klocale.h>
54 #include <kdatetime.h>
55 
56 #include <QtCore/QBuffer>
57 
58 #include <time.h>
59 
60 using namespace KCalCore;
61 using namespace KTnef;
62 
63 /*******************************************************************
64  * Helper functions for the msTNEF -> VPart converter
65  *******************************************************************/
66 
67 //-----------------------------------------------------------------------------
68 //@cond IGNORE
69 static 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 
75 static QString sNamedProp( KTNEFMessage *tnefMsg, const QString &name,
76  const QString &fallback = QString() )
77 {
78  return tnefMsg->findNamedProp( name, fallback );
79 }
80 
81 struct save_tz {
82  char *old_tz;
83  char *tz_env_str;
84 };
85 
86 /* temporarily go to a different timezone */
87 static 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 */
119 static 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 
140 static 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 
153 static 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 
196 QString 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
537 QString 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 
551 QString 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 
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:29:57 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

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

kdepimlibs-4.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 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