[pim/ktnef] src: Remove unused TNEF write support
Volker Krause <[email protected]> Tue, 4 Aug 2026 16:11:29 +0000 (UTC)
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 5960a6029d8c8c4fc4b0bc311825a08f5705057e by Volker Krause.
Committed on 04/08/2026 at 16:02.
Pushed by vkrause into branch 'master'.
Remove unused TNEF write support
M +0 -3 src/CMakeLists.txt
D +0 -507 src/ktnefwriter.cpp
D +0 -281 src/ktnefwriter.h
https://invent.kde.org/pim/ktnef/-/commit/5960a6029d8c8c4fc4b0bc311825a08f5705057e
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 55a0a3d..44a1433 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,7 +10,6 @@ target_sources(
mapi.cpp
ktnefpropertyset.cpp
ktnefmessage.cpp
- ktnefwriter.cpp
lzfu.cpp
formatter.cpp
ktnefpropertyset.h
@@ -21,7 +20,6 @@ target_sources(
ktnefmessage.h
ktnefdefs.h
formatter.h
- ktnefwriter.h
ktnefproperty.h
)
@@ -75,7 +73,6 @@ ecm_generate_headers(KTnef_CamelCase_HEADERS
KTNEFParser
KTNEFProperty
KTNEFPropertySet
- KTNEFWriter
PREFIX KTNEF
REQUIRED_HEADERS KTnef_HEADERS
)
diff --git a/src/ktnefwriter.cpp b/src/ktnefwriter.cpp
deleted file mode 100644
index b54eb8f..0000000
--- a/src/ktnefwriter.cpp
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- ktnefwriter.cpp
-
- SPDX-FileCopyrightText: 2002 Bo Thorsen <[email protected]>
-
- This file is part of KTNEF, the KDE TNEF support library/program.
-
- SPDX-License-Identifier: LGPL-2.0-or-later
- */
-/**
- * @file
- * This file is part of the API for handling TNEF data and
- * defines the KTNEFWriter class.
- *
- * @author Bo Thorsen
- */
-
-#include "ktnefwriter.h"
-using namespace Qt::Literals::StringLiterals;
-
-#include "ktnefdefs.h"
-#include "ktnefproperty.h"
-#include "ktnefpropertyset.h"
-
-#include "ktnef_debug.h"
-
-#include <QByteArray>
-#include <QDataStream>
-#include <QDateTime>
-#include <QIODevice>
-#include <QList>
-
-#include <cassert>
-
-using namespace KTnef;
-
-/**
- * KTNEFWriterPrivate class that helps to provide binary compatibility between releases.
- * @internal
- */
-//@cond PRIVATE
-class KTnef::KTNEFWriterPrivateData
-{
-public:
- KTNEFWriterPrivateData()
- : mFirstAttachNum(QDateTime::currentDateTimeUtc().toSecsSinceEpoch())
- {
- }
-
- KTNEFPropertySet properties;
- const quint16 mFirstAttachNum;
-};
-//@endcond
-
-KTNEFWriter::KTNEFWriter()
- : d(new KTnef::KTNEFWriterPrivateData)
-{
- // This is not something the user should fiddle with
- // First set the TNEF version
- QVariant v(0x00010000);
- addProperty(attTNEFVERSION, atpDWORD, v);
-
- // Now set the code page to something reasonable. TODO: Use the right one
- QVariant v1((quint32)0x4e4);
- QVariant v2((quint32)0x0);
- QList<QVariant> list;
- list << v1;
- list << v2;
- v = QVariant(list);
- addProperty(attOEMCODEPAGE, atpBYTE, list);
-}
-
-KTNEFWriter::~KTNEFWriter() = default;
-
-void KTNEFWriter::addProperty(int tag, int type, const QVariant &value)
-{
- d->properties.addProperty(tag, type, value);
-}
-
-//@cond IGNORE
-void addToChecksum(quint32 i, quint16 &checksum)
-{
- checksum += i & 0xff;
- checksum += (i >> 8) & 0xff;
- checksum += (i >> 16) & 0xff;
- checksum += (i >> 24) & 0xff;
-}
-
-void addToChecksum(const QByteArray &cs, quint16 &checksum)
-{
- int len = cs.length();
- for (int i = 0; i < len; i++) {
- checksum += (quint8)cs[i];
- }
-}
-
-void writeCString(QDataStream &stream, QByteArray &str)
-{
- stream.writeRawData(str.data(), str.length());
- stream << (quint8)0;
-}
-
-quint32 mergeTagAndType(quint32 tag, quint32 type)
-{
- return ((type & 0xffff) << 16) | (tag & 0xffff);
-}
-//@endcond
-
-/* This writes a TNEF property to the file.
- *
- * A TNEF property has a 1 byte type (LVL_MESSAGE or LVL_ATTACHMENT),
- * a 4 byte type/tag, a 4 byte length, the data and finally the checksum.
- *
- * The checksum is a 16 byte int with all bytes in the data added.
- */
-bool KTNEFWriter::writeProperty(QDataStream &stream, int &bytes, int tag) const
-{
- QMap<int, KTNEFProperty *> &properties = d->properties.properties();
- QMap<int, KTNEFProperty *>::Iterator it = properties.find(tag);
-
- if (it == properties.end()) {
- return false;
- }
-
- KTNEFProperty *property = *it;
-
- quint32 i;
- quint16 checksum = 0;
- QList<QVariant> list;
- QByteArray cs;
- QByteArray cs2;
- QDateTime dt;
- QDate date;
- QTime time;
- switch (tag) {
- case attMSGSTATUS:
- // quint8
- i = property->value().toUInt() & 0xff;
- checksum = i;
-
- stream << (quint8)LVL_MESSAGE;
- stream << mergeTagAndType(tag, property->type());
- stream << (quint32)1;
- stream << (quint8)i;
-
- bytes += 10;
- break;
-
- case attMSGPRIORITY:
- case attREQUESTRES:
- // quint16
- i = property->value().toUInt() & 0xffff;
- addToChecksum(i, checksum);
-
- stream << (quint8)LVL_MESSAGE;
- stream << mergeTagAndType(tag, property->type());
- stream << (quint32)2;
- stream << (quint16)i;
-
- bytes += 11;
- break;
-
- case attTNEFVERSION:
- // quint32
- i = property->value().toUInt();
- addToChecksum(i, checksum);
-
- stream << (quint8)LVL_MESSAGE;
- stream << mergeTagAndType(tag, property->type());
- stream << (quint32)4;
- stream << (quint32)i;
-
- bytes += 13;
- break;
-
- case attOEMCODEPAGE:
- // 2 quint32
- list = property->value().toList();
- assert(list.count() == 2);
-
- stream << (quint8)LVL_MESSAGE;
- stream << mergeTagAndType(tag, property->type());
- stream << (quint32)8;
-
- i = list[0].toInt();
- addToChecksum(i, checksum);
- stream << (quint32)i;
- i = list[1].toInt();
- addToChecksum(i, checksum);
- stream << (quint32)i;
-
- bytes += 17;
- break;
-
- case attMSGCLASS:
- case attSUBJECT:
- case attBODY:
- case attMSGID:
- // QCString
- cs = property->value().toString().toLocal8Bit();
- addToChecksum(cs, checksum);
-
- stream << (quint8)LVL_MESSAGE;
- stream << mergeTagAndType(tag, property->type());
- stream << (quint32)cs.length() + 1;
- writeCString(stream, cs);
-
- bytes += 9 + cs.length() + 1;
- break;
-
- case attFROM:
- // 2 QString encoded to a TRP structure
- list = property->value().toList();
- assert(list.count() == 2);
-
- cs = list[0].toString().toLocal8Bit(); // Name
- cs2 = QString("smtp:"_L1 + list[1].toString()).toLocal8Bit(); // Email address
- i = 18 + cs.length() + cs2.length(); // 2 * sizof(TRP) + strings + 2x'\0'
-
- stream << (quint8)LVL_MESSAGE;
- stream << mergeTagAndType(tag, property->type());
- stream << (quint32)i;
-
- // The stream has to be aligned to 4 bytes for the strings
- // TODO: Or does it? Looks like Outlook doesn't do this
- // bytes += 17;
- // Write the first TRP structure
- stream << (quint16)4; // trpidOneOff
- stream << (quint16)i; // totalsize
- stream << (quint16)(cs.length() + 1); // sizeof name
- stream << (quint16)(cs2.length() + 1); // sizeof address
-
- // if ( bytes % 4 != 0 )
- // Align the buffer
-
- // Write the strings
- writeCString(stream, cs);
- writeCString(stream, cs2);
-
- // Write the empty padding TRP structure (just zeroes)
- stream << (quint32)0 << (quint32)0;
-
- addToChecksum(4, checksum);
- addToChecksum(i, checksum);
- addToChecksum(cs.length() + 1, checksum);
- addToChecksum(cs2.length() + 1, checksum);
- addToChecksum(cs, checksum);
- addToChecksum(cs2, checksum);
-
- bytes += 10;
- break;
-
- case attDATESENT:
- case attDATERECD:
- case attDATEMODIFIED:
- // QDateTime
- dt = property->value().toDateTime();
- time = dt.time();
- date = dt.date();
-
- stream << (quint8)LVL_MESSAGE;
- stream << mergeTagAndType(tag, property->type());
- stream << (quint32)14;
-
- i = (quint16)date.year();
- addToChecksum(i, checksum);
- stream << (quint16)i;
- i = (quint16)date.month();
- addToChecksum(i, checksum);
- stream << (quint16)i;
- i = (quint16)date.day();
- addToChecksum(i, checksum);
- stream << (quint16)i;
- i = (quint16)time.hour();
- addToChecksum(i, checksum);
- stream << (quint16)i;
- i = (quint16)time.minute();
- addToChecksum(i, checksum);
- stream << (quint16)i;
- i = (quint16)time.second();
- addToChecksum(i, checksum);
- stream << (quint16)i;
- i = (quint16)date.dayOfWeek();
- addToChecksum(i, checksum);
- stream << (quint16)i;
- break;
- /*
- case attMSGSTATUS:
- {
- quint8 c;
- quint32 flag = 0;
- if ( c & fmsRead ) flag |= MSGFLAG_READ;
- if ( !( c & fmsModified ) ) flag |= MSGFLAG_UNMODIFIED;
- if ( c & fmsSubmitted ) flag |= MSGFLAG_SUBMIT;
- if ( c & fmsHasAttach ) flag |= MSGFLAG_HASATTACH;
- if ( c & fmsLocal ) flag |= MSGFLAG_UNSENT;
- d->stream_ >> c;
-
- i = property->value().toUInt();
- stream << (quint8)LVL_MESSAGE;
- stream << (quint32)type;
- stream << (quint32)2;
- stream << (quint8)i;
- addToChecksum( i, checksum );
- // from reader: d->message_->addProperty( 0x0E07, MAPI_TYPE_ULONG, flag );
- }
- qCDebug(KTNEF_LOG) << "Message Status" << "(length=" << i2 << ")";
- break;
- */
-
- default:
- qCDebug(KTNEF_LOG) << "Unknown TNEF tag:" << tag;
- return false;
- }
-
- stream << (quint16)checksum;
- return true;
-}
-
-bool KTNEFWriter::writeFile(QIODevice &file) const
-{
- if (!file.open(QIODevice::WriteOnly)) {
- return false;
- }
-
- QDataStream stream(&file);
- return writeFile(stream);
-}
-
-bool KTNEFWriter::writeFile(QDataStream &stream) const
-{
- stream.setByteOrder(QDataStream::LittleEndian);
-
- // Start by writing the opening TNEF stuff
- stream << TNEF_SIGNATURE;
-
- // Store the PR_ATTACH_NUM value for the first attachment
- // ( must be stored even if *no* attachments are stored )
- stream << d->mFirstAttachNum;
-
- // Now do some writing
- bool ok = true;
- int bytesWritten = 0;
- ok &= writeProperty(stream, bytesWritten, attTNEFVERSION);
- ok &= writeProperty(stream, bytesWritten, attOEMCODEPAGE);
- ok &= writeProperty(stream, bytesWritten, attMSGCLASS);
- ok &= writeProperty(stream, bytesWritten, attMSGPRIORITY);
- ok &= writeProperty(stream, bytesWritten, attSUBJECT);
- ok &= writeProperty(stream, bytesWritten, attDATESENT);
- ok &= writeProperty(stream, bytesWritten, attDATESTART);
- ok &= writeProperty(stream, bytesWritten, attDATEEND);
- // ok &= writeProperty( stream, bytesWritten, attAIDOWNER );
- ok &= writeProperty(stream, bytesWritten, attREQUESTRES);
- ok &= writeProperty(stream, bytesWritten, attFROM);
- ok &= writeProperty(stream, bytesWritten, attDATERECD);
- ok &= writeProperty(stream, bytesWritten, attMSGSTATUS);
- ok &= writeProperty(stream, bytesWritten, attBODY);
- return ok;
-}
-
-void KTNEFWriter::setSender(const QString &name, const QString &email)
-{
- assert(!name.isEmpty());
- assert(!email.isEmpty());
-
- QVariant v1(name);
- QVariant v2(email);
-
- const QList<QVariant> list = {v1, v2};
-
- addProperty(attFROM, 0, list); // What's up with the 0 here ??
-}
-
-void KTNEFWriter::setMessageType(MessageType m)
-{
- // Note that the MessageType list here is probably not long enough,
- // more entries are most likely needed later
-
- QVariant v;
- switch (m) {
- case Appointment:
- v = QVariant("IPM.Appointment"_L1);
- break;
-
- case MeetingCancelled:
- v = QVariant("IPM.Schedule.Meeting.Cancelled"_L1);
- break;
-
- case MeetingRequest:
- v = QVariant("IPM.Schedule.Meeting.Request"_L1);
- break;
-
- case MeetingNo:
- v = QVariant("IPM.Schedule.Meeting.Resp.Neg"_L1);
- break;
-
- case MeetingYes:
- v = QVariant("IPM.Schedule.Meeting.Resp.Pos"_L1);
- break;
-
- case MeetingTent:
- // Tent?
- v = QVariant("IPM.Schedule.Meeting.Resp.Tent"_L1);
- break;
-
- default:
- return;
- }
-
- addProperty(attMSGCLASS, atpWORD, v);
-}
-
-void KTNEFWriter::setMethod(Method)
-{
-}
-
-void KTNEFWriter::clearAttendees()
-{
-}
-
-void KTNEFWriter::addAttendee(const QString &cn, Role r, PartStat p, bool rsvp, const QString &mailto)
-{
- Q_UNUSED(cn)
- Q_UNUSED(r)
- Q_UNUSED(p)
- Q_UNUSED(rsvp)
- Q_UNUSED(mailto)
-}
-
-// I assume this is the same as the sender?
-// U also assume that this is like "Name <address>"
-void KTNEFWriter::setOrganizer(const QString &organizer)
-{
- int i = organizer.indexOf(u'<');
-
- if (i == -1) {
- return;
- }
-
- QString name = organizer.left(i).trimmed();
-
- QString email = organizer.right(i + 1);
- email = email.left(email.length() - 1).trimmed();
-
- setSender(name, email);
-}
-
-void KTNEFWriter::setDtStart(const QDateTime &dtStart)
-{
- QVariant v(dtStart);
- addProperty(attDATESTART, atpDATE, v);
-}
-
-void KTNEFWriter::setDtEnd(const QDateTime &dtEnd)
-{
- QVariant v(dtEnd);
- addProperty(attDATEEND, atpDATE, v);
-}
-
-void KTNEFWriter::setLocation(const QString & /*location*/)
-{
-}
-
-void KTNEFWriter::setUID(const QString &uid)
-{
- QVariant v(uid);
- addProperty(attMSGID, atpSTRING, v);
-}
-
-// Date sent
-void KTNEFWriter::setDtStamp(const QDateTime &dtStamp)
-{
- QVariant v(dtStamp);
- addProperty(attDATESENT, atpDATE, v);
-}
-
-void KTNEFWriter::setCategories(const QStringList &)
-{
-}
-
-// I hope this is the body
-void KTNEFWriter::setDescription(const QString &body)
-{
- QVariant v(body);
- addProperty(attBODY, atpTEXT, v);
-}
-
-void KTNEFWriter::setSummary(const QString &s)
-{
- QVariant v(s);
- addProperty(attSUBJECT, atpSTRING, v);
-}
-
-// TNEF encoding: Normal = 3, high = 2, low = 1
-// MAPI encoding: Normal = -1, high = 0, low = 1
-void KTNEFWriter::setPriority(Priority p)
-{
- QVariant v((quint32)p);
- addProperty(attMSGPRIORITY, atpSHORT, v);
-}
-
-void KTNEFWriter::setAlarm(const QString &description, AlarmAction action, const QDateTime &wakeBefore)
-{
- Q_UNUSED(description)
- Q_UNUSED(action)
- Q_UNUSED(wakeBefore)
-}
diff --git a/src/ktnefwriter.h b/src/ktnefwriter.h
deleted file mode 100644
index 68fce31..0000000
--- a/src/ktnefwriter.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- ktnefwriter.cpp
-
- SPDX-FileCopyrightText: 2002 Bo Thorsen <[email protected]>
-
- This file is part of KTNEF, the KDE TNEF support library/program.
-
- SPDX-License-Identifier: LGPL-2.0-or-later
- */
-/*!
- * @file
- * This file is part of the API for handling TNEF data and
- * defines the KTNEFWriter class.
- *
- * @author Bo Thorsen
- */
-
-#pragma once
-#include <QStringList>
-
-#include "ktnef_export.h"
-#include <memory>
-#include <qglobal.h>
-
-class QString;
-class QVariant;
-class QIODevice;
-class QDataStream;
-class QDateTime;
-
-namespace KTnef
-{
-class KTNEFWriterPrivateData;
-/*!
- * \brief
- * Manages the writing of @acronym TNEF attachments.
- */
-class KTNEF_EXPORT KTNEFWriter
-{
-public:
- /*!
- * The different types of messages.
- */
- enum MessageType {
- Appointment, /*!< Appointment */
- MeetingCancelled, /*!< The meeting is cancelled */
- MeetingRequest, /*!< Meeting request */
- MeetingNo, /*!< Negative response to a meeting request */
- MeetingYes, /*!< Affirmative response to a meeting request */
- MeetingTent /*!< Tentative affirmative to a meeting request */
- };
-
- /*!
- * The different types of message statuses.
- */
- enum Method {
- PublishNew, /*!< Publish new */
- Obsolete, /*!< Replace the message */
- RequestNew, /*!< Request a new message */
- RequestUpdate, /*!< Request an update */
- Unknown /*!< Unknown */
- };
-
- /*!
- * The different types of meeting roles.
- */
- enum Role {
- ReqParticipant, /*!< Required participant */
- OptParticipant, /*!< Optional participant */
- NonParticipant, /*!< Non-participant */
- Chair /*!< Meeting chairperson */
- };
-
- /*!
- * The different types of participant statuses.
- */
- enum PartStat {
- NeedsAction, /*!< No information about the task/invitation received */
- Accepted, /*!< Accepted the task/invitation */
- Declined, /*!< Declined the task/invitation */
- Tentative, /*!< Tentatively accepted the task/invitation */
- Delegated, /*!< Delegated the task to another */
- Completed, /*!< Completed the task */
- InProcess /*!< Work on the task is in-progress */
- };
-
- /*!
- * The different priorities.
- */
- enum Priority {
- High = 2, /*!< High priority task */
- Normal = 3, /*!< Normal priority task */
- Low = 1 /*!< Low priority task */
- };
-
- /*!
- * The different alarm actions.
- */
- enum AlarmAction {
- Display /*!< Display the alarm */
- };
-
- /*!
- * Constructs a @acronym TNEF writer object.
- */
- KTNEFWriter();
-
- /*!
- * Destroys the @acronym TNEF writer object.
- */
- ~KTNEFWriter();
-
- /*!
- * Adds a @acronym TNEF property.
- *
- * \a tag is the @acronym TNEF tag
- * \a type is the property type
- * \a value is the property value
- */
- void addProperty(int tag, int type, const QVariant &value);
-
- /*!
- * Writes a @acronym TNEF property to the #QDataStream specified by \a stream.
- *
- * A @acronym TNEF property has a 1 byte type (LVL_MESSAGE or LVL_ATTACHMENT),
- * a 4 byte type/tag, a 4 byte length, the data and finally the checksum.
- *
- * The checksum is a 16 byte int with all bytes in the data added.
- *
- * \a stream is the #QDataStream to write
- * \a bytes is a pointer to an int type that will contain
- * the number of bytes written to the \a stream
- * \a tag is the @acronym TNEF tag
- *
- * Returns false if an invalid @acronym TNEF tag was specified by \a tag or
- * if there are no properties to write; else true.
- */
- [[nodiscard]] bool writeProperty(QDataStream &stream, int &bytes, int tag) const;
-
- /*!
- * Writes the attachment to the #QIODevice specified by \a file.
- *
- * \a file is the #QIODevice to write.
- * Returns true if the write was successful; otherwise false.
- */
- [[nodiscard]] bool writeFile(QIODevice &file) const;
-
- /*!
- * Writes the attachment to the #QDataStream specified by \a stream.
- *
- * \a stream is the #QDataStream to write.
- * Returns true if the write was successful; otherwise false.
- */
- [[nodiscard]] bool writeFile(QDataStream &stream) const;
-
- /*!
- * Sets the sender's \a name and \a email address.
- *
- * \a name is the sender's name.
- * \a email is the sender's email address.
- */
- void setSender(const QString &name, const QString &email);
-
- /*!
- * Sets the #MessageType to \a methodType.
- *
- * \a methodType is the #MessageType.
- */
- void setMessageType(MessageType methodType);
-
- /*!
- * Sets the #Method to \a method.
- *
- * \a method is the #Method.
- */
- void setMethod(Method method);
-
- /*!
- * Clears the attendees list.
- */
- void clearAttendees();
-
- /*!
- * Adds a meeting participant (attendee).
- *
- * \a name is the name of the attendee
- * \a role is the #Role of the attendee
- * \a partstat is the status #PartStat of the attendee
- * \a rsvp is true if the attendee will attend the meeting; else false
- * \a email is the email address of the attendee
- */
- void addAttendee(const QString &name, Role role, PartStat partstat, bool rsvp, const QString &email);
-
- /*!
- * Sets the name of the organizer to \a organizer.
- * The organizer is any string identifier; it could be the name
- * of a person, or the application that sent the invitation, for example.
- *
- * \a organizer is the organizer identifier.
- */
- void setOrganizer(const QString &organizer);
-
- /*!
- * Sets the Starting Date and Time to \a dtStart.
- *
- * \a dtStart is the starting date/time.
- */
- void setDtStart(const QDateTime &dtStart);
-
- /*!
- * Sets the Ending Date and Time to \a dtEnd.
- *
- * \a dtEnd is the ending date/time.
- */
- void setDtEnd(const QDateTime &dtEnd);
-
- /*!
- * Sets the Location to \a location.
- *
- * \a location is the location.
- */
- void setLocation(const QString &location);
-
- /*!
- * Sets the @acronym UID to \a uid.
- *
- * \a uid is the @acronym UID.
- */
- void setUID(const QString &uid);
-
- /*!
- * Sets the timestamp to \a dtStamp.
- *
- * \a dtStamp is the timestamp.
- */
- void setDtStamp(const QDateTime &dtStamp);
-
- /*!
- * Sets the category list to \a categories.
- *
- * \a categories is the list categories.
- */
- void setCategories(const QStringList &categories);
-
- /*!
- * Sets the description to \a description.
- *
- * \a description is the description.
- */
- void setDescription(const QString &description);
-
- /*!
- * Sets the summary to \a summary.
- *
- * \a summary is the summary.
- */
- void setSummary(const QString &summary);
-
- /*!
- * Sets the priority to \a priority.
- *
- * \a priority is the #Priority.
- */
- void setPriority(Priority priority);
-
- /*!
- * Sets the alarm.
- *
- * \a description is the alarm description
- * \a action is the alaram #AlarmAction
- * \a wakeBefore is the alarm Date/Time
- */
- void setAlarm(const QString &description, AlarmAction action, const QDateTime &wakeBefore);
-
-private:
- std::unique_ptr<KTNEFWriterPrivateData> const d;
-
- Q_DISABLE_COPY(KTNEFWriter)
-};
-
-}