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

KTNEF Library

  • sources
  • kde-4.14
  • kdepimlibs
  • ktnef
ktnefwriter.cpp
Go to the documentation of this file.
1 /*
2  ktnefwriter.cpp
3 
4  Copyright (C) 2002 Bo Thorsen <bo@sonofthor.dk>
5 
6  This file is part of KTNEF, the KDE TNEF support library/program.
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Library General Public License for more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22  */
31 #include "ktnefwriter.h"
32 #include "ktnefproperty.h"
33 #include "ktnefpropertyset.h"
34 #include "ktnefdefs.h"
35 
36 #include <kdebug.h>
37 
38 #include <QtCore/QFile>
39 #include <QtCore/QDateTime>
40 #include <QtCore/QDataStream>
41 #include <QtCore/QList>
42 #include <QtCore/QByteArray>
43 
44 #include <assert.h>
45 
46 using namespace KTnef;
47 
52 //@cond PRIVATE
53 class KTnef::KTNEFWriter::PrivateData
54 {
55  public:
56  PrivateData() { mFirstAttachNum = QDateTime::currentDateTime().toTime_t(); }
57  KTNEFPropertySet properties;
58  quint16 mFirstAttachNum;
59 };
60 //@endcond
61 
62 KTNEFWriter::KTNEFWriter() : d( new KTnef::KTNEFWriter::PrivateData )
63 {
64  // This is not something the user should fiddle with
65  // First set the TNEF version
66  QVariant v(0x00010000);
67  addProperty( attTNEFVERSION, atpDWORD, v );
68 
69  // Now set the code page to something reasonable. TODO: Use the right one
70  QVariant v1( (quint32)0x4e4 );
71  QVariant v2( (quint32)0x0 );
72  QList<QVariant> list;
73  list << v1;
74  list << v2;
75  v = QVariant( list );
76  addProperty( attOEMCODEPAGE, atpBYTE, list );
77 }
78 
79 KTNEFWriter::~KTNEFWriter()
80 {
81  delete d;
82 }
83 
84 void KTNEFWriter::addProperty( int tag, int type, const QVariant &value )
85 {
86  d->properties.addProperty( tag, type, value );
87 }
88 
89 //@cond IGNORE
90 void addToChecksum( quint32 i, quint16 &checksum )
91 {
92  checksum += i & 0xff;
93  checksum += ( i >> 8 ) & 0xff;
94  checksum += ( i >> 16 ) & 0xff;
95  checksum += ( i >> 24 ) & 0xff;
96 }
97 
98 void addToChecksum( QByteArray &cs, quint16 &checksum )
99 {
100  int len = cs.length();
101  for ( int i=0; i<len; i++ ) {
102  checksum += (quint8)cs[i];
103  }
104 }
105 
106 void writeCString( QDataStream &stream, QByteArray &str )
107 {
108  stream.writeRawData( str.data(), str.length() );
109  stream << (quint8)0;
110 }
111 
112 quint32 mergeTagAndType( quint32 tag, quint32 type )
113 {
114  return ( ( type & 0xffff ) << 16 ) | ( tag & 0xffff );
115 }
116 //@endcond
117 
118 /* This writes a TNEF property to the file.
119  *
120  * A TNEF property has a 1 byte type (LVL_MESSAGE or LVL_ATTACHMENT),
121  * a 4 byte type/tag, a 4 byte length, the data and finally the checksum.
122  *
123  * The checksum is a 16 byte int with all bytes in the data added.
124  */
125 bool KTNEFWriter::writeProperty( QDataStream &stream, int &bytes, int tag ) const
126 {
127  QMap<int,KTNEFProperty*>& properties = d->properties.properties();
128  QMap<int,KTNEFProperty*>::Iterator it = properties.find( tag );
129 
130  if ( it == properties.end() ) {
131  return false;
132  }
133 
134  KTNEFProperty *property = *it;
135 
136  quint32 i;
137  quint16 checksum = 0;
138  QList<QVariant> list;
139  QString s;
140  QByteArray cs, cs2;
141  QDateTime dt;
142  QDate date;
143  QTime time;
144  switch( tag ) {
145  case attMSGSTATUS:
146  // quint8
147  i = property->value().toUInt() & 0xff;
148  checksum = i;
149 
150  stream << (quint8)LVL_MESSAGE;
151  stream << mergeTagAndType( tag, property->type() );
152  stream << (quint32)1;
153  stream << (quint8)i;
154 
155  bytes += 10;
156  break;
157 
158  case attMSGPRIORITY:
159  case attREQUESTRES:
160  // quint16
161  i = property->value().toUInt() & 0xffff;
162  addToChecksum( i, checksum );
163 
164  stream << (quint8)LVL_MESSAGE;
165  stream << mergeTagAndType( tag, property->type() );
166  stream << (quint32)2;
167  stream << (quint16)i;
168 
169  bytes += 11;
170  break;
171 
172  case attTNEFVERSION:
173  // quint32
174  i = property->value().toUInt();
175  addToChecksum( i, checksum );
176 
177  stream << (quint8)LVL_MESSAGE;
178  stream << mergeTagAndType( tag, property->type() );
179  stream << (quint32)4;
180  stream << (quint32)i;
181 
182  bytes += 13;
183  break;
184 
185  case attOEMCODEPAGE:
186  // 2 quint32
187  list = property->value().toList();
188  assert( list.count() == 2 );
189 
190  stream << (quint8)LVL_MESSAGE;
191  stream << mergeTagAndType( tag, property->type() );
192  stream << (quint32)8;
193 
194  i = list[0].toInt();
195  addToChecksum( i, checksum );
196  stream << (quint32)i;
197  i = list[1].toInt();
198  addToChecksum( i, checksum );
199  stream << (quint32)i;
200 
201  bytes += 17;
202  break;
203 
204  case attMSGCLASS:
205  case attSUBJECT:
206  case attBODY:
207  case attMSGID:
208  // QCString
209  cs = property->value().toString().toLocal8Bit();
210  addToChecksum( cs, checksum );
211 
212  stream << (quint8)LVL_MESSAGE;
213  stream << mergeTagAndType( tag, property->type() );
214  stream << (quint32)cs.length()+1;
215  writeCString( stream, cs );
216 
217  bytes += 9 + cs.length()+1;
218  break;
219 
220  case attFROM:
221  // 2 QString encoded to a TRP structure
222  list = property->value().toList();
223  assert( list.count() == 2 );
224 
225  cs = list[0].toString().toLocal8Bit(); // Name
226  cs2 = QString( QLatin1String( "smtp:" ) + list[1].toString() ).toLocal8Bit(); // Email address
227  i = 18 + cs.length() + cs2.length(); // 2 * sizof(TRP) + strings + 2x'\0'
228 
229  stream << (quint8)LVL_MESSAGE;
230  stream << mergeTagAndType( tag, property->type() );
231  stream << (quint32)i;
232 
233  // The stream has to be aligned to 4 bytes for the strings
234  // TODO: Or does it? Looks like Outlook doesn't do this
235  // bytes += 17;
236  // Write the first TRP structure
237  stream << (quint16)4; // trpidOneOff
238  stream << (quint16)i; // totalsize
239  stream << (quint16)( cs.length() + 1 ); // sizeof name
240  stream << (quint16)( cs2.length() + 1 );// sizeof address
241 
242  // if ( bytes % 4 != 0 )
243  // Align the buffer
244 
245  // Write the strings
246  writeCString( stream, cs );
247  writeCString( stream, cs2 );
248 
249  // Write the empty padding TRP structure (just zeroes)
250  stream << (quint32)0 << (quint32)0;
251 
252  addToChecksum( 4, checksum );
253  addToChecksum( i, checksum );
254  addToChecksum( cs.length()+1, checksum );
255  addToChecksum( cs2.length()+1, checksum );
256  addToChecksum( cs, checksum );
257  addToChecksum( cs2, checksum );
258 
259  bytes += 10;
260  break;
261 
262  case attDATESENT:
263  case attDATERECD:
264  case attDATEMODIFIED:
265  // QDateTime
266  dt = property->value().toDateTime();
267  time = dt.time();
268  date = dt.date();
269 
270  stream << (quint8)LVL_MESSAGE;
271  stream << mergeTagAndType( tag, property->type() );
272  stream << (quint32)14;
273 
274  i = (quint16)date.year();
275  addToChecksum( i, checksum );
276  stream << (quint16)i;
277  i = (quint16)date.month();
278  addToChecksum( i, checksum );
279  stream << (quint16)i;
280  i = (quint16)date.day();
281  addToChecksum( i, checksum );
282  stream << (quint16)i;
283  i = (quint16)time.hour();
284  addToChecksum( i, checksum );
285  stream << (quint16)i;
286  i = (quint16)time.minute();
287  addToChecksum( i, checksum );
288  stream << (quint16)i;
289  i = (quint16)time.second();
290  addToChecksum( i, checksum );
291  stream << (quint16)i;
292  i = (quint16)date.dayOfWeek();
293  addToChecksum( i, checksum );
294  stream << (quint16)i;
295  break;
296 /*
297  case attMSGSTATUS:
298  {
299  quint8 c;
300  quint32 flag = 0;
301  if ( c & fmsRead ) flag |= MSGFLAG_READ;
302  if ( !( c & fmsModified ) ) flag |= MSGFLAG_UNMODIFIED;
303  if ( c & fmsSubmitted ) flag |= MSGFLAG_SUBMIT;
304  if ( c & fmsHasAttach ) flag |= MSGFLAG_HASATTACH;
305  if ( c & fmsLocal ) flag |= MSGFLAG_UNSENT;
306  d->stream_ >> c;
307 
308  i = property->value().toUInt();
309  stream << (quint8)LVL_MESSAGE;
310  stream << (quint32)type;
311  stream << (quint32)2;
312  stream << (quint8)i;
313  addToChecksum( i, checksum );
314  // from reader: d->message_->addProperty( 0x0E07, MAPI_TYPE_ULONG, flag );
315  }
316  kDebug() << "Message Status" << "(length=" << i2 << ")";
317  break;
318 */
319 
320  default:
321  kDebug() << "Unknown TNEF tag:" << tag;
322  return false;
323  }
324 
325  stream << (quint16)checksum;
326  return true;
327 }
328 
329 bool KTNEFWriter::writeFile( QIODevice &file ) const
330 {
331  if ( !file.open( QIODevice::WriteOnly ) ) {
332  return false;
333  }
334 
335  QDataStream stream( &file );
336  return writeFile( stream );
337 }
338 
339 bool KTNEFWriter::writeFile( QDataStream &stream ) const
340 {
341  stream.setByteOrder( QDataStream::LittleEndian );
342 
343  // Start by writing the opening TNEF stuff
344  stream << TNEF_SIGNATURE;
345 
346  // Store the PR_ATTACH_NUM value for the first attachment
347  // ( must be stored even if *no* attachments are stored )
348  stream << d->mFirstAttachNum;
349 
350  // Now do some writing
351  bool ok = true;
352  int bytesWritten = 0;
353  ok &= writeProperty( stream, bytesWritten, attTNEFVERSION );
354  ok &= writeProperty( stream, bytesWritten, attOEMCODEPAGE );
355  ok &= writeProperty( stream, bytesWritten, attMSGCLASS );
356  ok &= writeProperty( stream, bytesWritten, attMSGPRIORITY );
357  ok &= writeProperty( stream, bytesWritten, attSUBJECT );
358  ok &= writeProperty( stream, bytesWritten, attDATESENT );
359  ok &= writeProperty( stream, bytesWritten, attDATESTART );
360  ok &= writeProperty( stream, bytesWritten, attDATEEND );
361  // ok &= writeProperty( stream, bytesWritten, attAIDOWNER );
362  ok &= writeProperty( stream, bytesWritten, attREQUESTRES );
363  ok &= writeProperty( stream, bytesWritten, attFROM );
364  ok &= writeProperty( stream, bytesWritten, attDATERECD );
365  ok &= writeProperty( stream, bytesWritten, attMSGSTATUS );
366  ok &= writeProperty( stream, bytesWritten, attBODY );
367  return ok;
368 }
369 
370 void KTNEFWriter::setSender( const QString &name, const QString &email )
371 {
372  assert( !name.isEmpty() );
373  assert( !email.isEmpty() );
374 
375  QVariant v1( name );
376  QVariant v2( email );
377 
378  QList<QVariant> list;
379  list << v1;
380  list << v2;
381 
382  QVariant v( list );
383  addProperty( attFROM, 0, list ); // What's up with the 0 here ??
384 }
385 
386 void KTNEFWriter::setMessageType( MessageType m )
387 {
388  // Note that the MessageType list here is probably not long enough,
389  // more entries are most likely needed later
390 
391  QVariant v;
392  switch( m ) {
393  case Appointment:
394  v = QVariant( QString( "IPM.Appointment" ) );
395  break;
396 
397  case MeetingCancelled:
398  v = QVariant( QString( "IPM.Schedule.Meeting.Cancelled" ) );
399  break;
400 
401  case MeetingRequest:
402  v = QVariant( QString( "IPM.Schedule.Meeting.Request" ) );
403  break;
404 
405  case MeetingNo:
406  v = QVariant( QString( "IPM.Schedule.Meeting.Resp.Neg" ) );
407  break;
408 
409  case MeetingYes:
410  v = QVariant( QString( "IPM.Schedule.Meeting.Resp.Pos" ) );
411  break;
412 
413  case MeetingTent:
414  // Tent?
415  v = QVariant( QString( "IPM.Schedule.Meeting.Resp.Tent" ) );
416  break;
417 
418  default:
419  return;
420  }
421 
422  addProperty( attMSGCLASS, atpWORD, v );
423 }
424 
425 void KTNEFWriter::setMethod( Method )
426 {
427 
428 }
429 
430 void KTNEFWriter::clearAttendees()
431 {
432 
433 }
434 
435 void KTNEFWriter::addAttendee( const QString &cn, Role r,
436  PartStat p, bool rsvp,
437  const QString &mailto )
438 {
439  Q_UNUSED( cn );
440  Q_UNUSED( r );
441  Q_UNUSED( p );
442  Q_UNUSED( rsvp );
443  Q_UNUSED( mailto );
444 }
445 
446 // I assume this is the same as the sender?
447 // U also assume that this is like "Name <address>"
448 void KTNEFWriter::setOrganizer( const QString &organizer )
449 {
450  int i = organizer.indexOf( '<' );
451 
452  if ( i == -1 ) {
453  return;
454  }
455 
456  QString name = organizer.left( i ).trimmed();
457 
458  QString email = organizer.right( i+1 );
459  email = email.left( email.length()-1 ).trimmed();
460 
461  setSender( name, email );
462 }
463 
464 void KTNEFWriter::setDtStart( const QDateTime &dtStart )
465 {
466  QVariant v( dtStart );
467  addProperty( attDATESTART, atpDATE, v );
468 }
469 
470 void KTNEFWriter::setDtEnd( const QDateTime &dtEnd )
471 {
472  QVariant v( dtEnd );
473  addProperty( attDATEEND, atpDATE, v );
474 }
475 
476 void KTNEFWriter::setLocation( const QString &/*location*/ )
477 {
478 
479 }
480 
481 void KTNEFWriter::setUID( const QString &uid )
482 {
483  QVariant v( uid );
484  addProperty( attMSGID, atpSTRING, v );
485 }
486 
487 // Date sent
488 void KTNEFWriter::setDtStamp( const QDateTime &dtStamp )
489 {
490  QVariant v( dtStamp );
491  addProperty( attDATESENT, atpDATE, v );
492 }
493 
494 void KTNEFWriter::setCategories( const QStringList &)
495 {
496 
497 }
498 
499 // I hope this is the body
500 void KTNEFWriter::setDescription( const QString &body )
501 {
502  QVariant v( body );
503  addProperty( attBODY, atpTEXT, v );
504 }
505 
506 void KTNEFWriter::setSummary( const QString &s )
507 {
508  QVariant v( s );
509  addProperty( attSUBJECT, atpSTRING, v );
510 }
511 
512 // TNEF encoding: Normal = 3, high = 2, low = 1
513 // MAPI encoding: Normal = -1, high = 0, low = 1
514 void KTNEFWriter::setPriority( Priority p )
515 {
516  QVariant v( (quint32)p );
517  addProperty( attMSGPRIORITY, atpSHORT, v );
518 }
519 
520 void KTNEFWriter::setAlarm( const QString &description,
521  AlarmAction action,
522  const QDateTime &wakeBefore )
523 {
524  Q_UNUSED( description );
525  Q_UNUSED( action );
526  Q_UNUSED( wakeBefore );
527 }
QIODevice
KTnef::KTNEFWriter::setSender
void setSender(const QString &name, const QString &email)
Sets the sender's name and email address.
Definition: ktnefwriter.cpp:370
KTnef::KTNEFWriter::setOrganizer
void setOrganizer(const QString &organizer)
Sets the name of the organizer to organizer.
Definition: ktnefwriter.cpp:448
QTime::minute
int minute() const
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KTnef::KTNEFWriter::Priority
Priority
The different priorities.
Definition: ktnefwriter.h:102
KTnef::KTNEFWriter::MeetingTent
Tentative affirmative to a meeting request.
Definition: ktnefwriter.h:62
KTnef::KTNEFWriter::setDtEnd
void setDtEnd(const QDateTime &dtEnd)
Sets the Ending Date and Time to dtEnd.
Definition: ktnefwriter.cpp:470
QByteArray
KTnef::KTNEFWriter::PartStat
PartStat
The different types of participant statuses.
Definition: ktnefwriter.h:89
KTnef::KTNEFWriter::MeetingRequest
Meeting request.
Definition: ktnefwriter.h:59
KTnef::KTNEFWriter::addProperty
void addProperty(int tag, int type, const QVariant &value)
Adds a TNEF property.
Definition: ktnefwriter.cpp:84
QDataStream
KTnef::KTNEFWriter::MeetingNo
Negative response to a meeting request.
Definition: ktnefwriter.h:60
QMap
QDateTime::time
QTime time() const
KTnef::KTNEFWriter::setCategories
void setCategories(const QStringList &categories)
Sets the category list to categories.
Definition: ktnefwriter.cpp:494
KTnef::KTNEFWriter::MeetingYes
Affirmative response to a meeting request.
Definition: ktnefwriter.h:61
KTnef::KTNEFWriter
Manages the writing of TNEF attachments.
Definition: ktnefwriter.h:50
QByteArray::length
int length() const
QIODevice::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QDate::month
int month() const
KTnef::KTNEFWriter::MeetingCancelled
The meeting is cancelled.
Definition: ktnefwriter.h:58
QTime
KTnef::KTNEFWriter::setLocation
void setLocation(const QString &location)
Sets the Location to location.
Definition: ktnefwriter.cpp:476
QTime::second
int second() const
KTnef::KTNEFWriter::MessageType
MessageType
The different types of messages.
Definition: ktnefwriter.h:56
QList::value
T value(int i) const
QDate::dayOfWeek
int dayOfWeek() const
KTnef::KTNEFWriter::setDescription
void setDescription(const QString &description)
Sets the description to description.
Definition: ktnefwriter.cpp:500
ktnefdefs.h
This file is part of the API for handling TNEF data and provides some basic definitions for general u...
KTnef::KTNEFWriter::addAttendee
void addAttendee(const QString &name, Role role, PartStat partstat, bool rsvp, const QString &email)
Adds a meeting participant (attendee).
Definition: ktnefwriter.cpp:435
KTnef::KTNEFPropertySet
Interface for setting MAPI properties and TNEF attributes.
Definition: ktnefpropertyset.h:48
QList::count
int count(const T &value) const
KTnef::KTNEFWriter::setSummary
void setSummary(const QString &summary)
Sets the summary to summary.
Definition: ktnefwriter.cpp:506
QString::isEmpty
bool isEmpty() const
QString::trimmed
QString trimmed() const
QDate::day
int day() const
KTnef::KTNEFWriter::KTNEFWriter
KTNEFWriter()
Constructs a TNEF writer object.
Definition: ktnefwriter.cpp:62
KTnef::KTNEFWriter::setMethod
void setMethod(Method method)
Sets the Method to method.
Definition: ktnefwriter.cpp:425
KTnef::KTNEFWriter::setPriority
void setPriority(Priority priority)
Sets the priority to priority.
Definition: ktnefwriter.cpp:514
QDate
QDate::year
int year() const
QString
QList
KTnef::KTNEFWriter::Role
Role
The different types of meeting roles.
Definition: ktnefwriter.h:79
QMap::end
iterator end()
KTnef::KTNEFWriter::setDtStart
void setDtStart(const QDateTime &dtStart)
Sets the Starting Date and Time to dtStart.
Definition: ktnefwriter.cpp:464
QStringList
QString::right
QString right(int n) const
KTnef::KTNEFWriter::setUID
void setUID(const QString &uid)
Sets the UID to uid.
Definition: ktnefwriter.cpp:481
QTime::hour
int hour() const
QString::toLocal8Bit
QByteArray toLocal8Bit() const
ktnefwriter.h
This file is part of the API for handling TNEF data and defines the KTNEFWriter class.
QDateTime::toTime_t
uint toTime_t() const
KTnef::KTNEFWriter::clearAttendees
void clearAttendees()
Clears the attendees list.
Definition: ktnefwriter.cpp:430
QDataStream::setByteOrder
void setByteOrder(ByteOrder bo)
QDateTime::currentDateTime
QDateTime currentDateTime()
ktnefpropertyset.h
This file is part of the API for handling TNEF data and defines the KTNEFPropertySet class...
QDateTime::date
QDate date() const
QLatin1String
ktnefproperty.h
This file is part of the API for handling TNEF data and defines the KTNEFProperty class...
KTnef::KTNEFWriter::Method
Method
The different types of message statuses.
Definition: ktnefwriter.h:68
KTnef::KTNEFWriter::setDtStamp
void setDtStamp(const QDateTime &dtStamp)
Sets the timestamp to dtStamp.
Definition: ktnefwriter.cpp:488
QDataStream::writeRawData
int writeRawData(const char *s, int len)
QString::length
int length() const
QByteArray::data
char * data()
QString::left
QString left(int n) const
KTnef::KTNEFWriter::Appointment
Appointment.
Definition: ktnefwriter.h:57
KTnef::KTNEFProperty
Interface for setting MAPI properties.
Definition: ktnefproperty.h:44
QMap::find
iterator find(const Key &key)
KTnef::KTNEFWriter::setMessageType
void setMessageType(MessageType methodType)
Sets the MessageType to methodType.
Definition: ktnefwriter.cpp:386
KTnef::KTNEFWriter::writeFile
bool writeFile(QIODevice &file) const
Writes the attachment to the QIODevice specified by file.
Definition: ktnefwriter.cpp:329
KTnef::KTNEFWriter::~KTNEFWriter
~KTNEFWriter()
Destroys the TNEF writer object.
Definition: ktnefwriter.cpp:79
QDateTime
KTnef::KTNEFWriter::writeProperty
bool writeProperty(QDataStream &stream, int &bytes, int tag) const
Writes a TNEF property to the QDataStream specified by stream.
Definition: ktnefwriter.cpp:125
KTnef::KTNEFWriter::setAlarm
void setAlarm(const QString &description, AlarmAction action, const QDateTime &wakeBefore)
Sets the alarm.
Definition: ktnefwriter.cpp:520
QVariant
KTnef::KTNEFWriter::AlarmAction
AlarmAction
The different alarm actions.
Definition: ktnefwriter.h:111
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:38:43 by doxygen 1.8.7 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 API Reference

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

Search



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