From 90bf33ec0bae5604ab4e574d61f7fe4c2bc9c1b9 Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Mon, 4 Jan 2021 15:40:08 +0000 Subject: [PATCH] [messagingframework] Add QMailMessage::CalendarCancellation flag. Contributes to JB#46945 Introduces a CalendarCancellation flag similar to the QMailMessage::CalendarInvitation to be matched against the QMailMessage::status() bitfield. While the CalendarInvitation flag indicates that the message contains an attachment of type text/calendar with "REQUEST" method, the CalendarCancellation flag indicates that there's an attachment of type text/calendar with "CANCEL" method type. In other words, a calendar event cancellation. For reference, the "CANCEL" method of the Content Type header is described in RFC2447 (iMIP) Section 2.4 [1] in combination with the RFC2446 (iTIP) sections 3.2 and 3.2.5 [2] [1] https://tools.ietf.org/html/rfc2447#section-2.4 [2] https://tools.ietf.org/html/rfc2446#section-3.2 --- ...ailMessage-CalendarCancellation-flag.patch | 201 ++++++++++++++++++ rpm/qmf-qt5.spec | 3 +- 2 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 rpm/0029-Add-QMailMessage-CalendarCancellation-flag.patch diff --git a/rpm/0029-Add-QMailMessage-CalendarCancellation-flag.patch b/rpm/0029-Add-QMailMessage-CalendarCancellation-flag.patch new file mode 100644 index 0000000..8860693 --- /dev/null +++ b/rpm/0029-Add-QMailMessage-CalendarCancellation-flag.patch @@ -0,0 +1,201 @@ +From 45fb98f4a669025e104121cb81eada87d7b01a3d Mon Sep 17 00:00:00 2001 +From: David Llewellyn-Jones +Date: Mon, 4 Jan 2021 15:21:12 +0000 +Subject: [PATCH] Add QMailMessage::CalendarCancellation flag + +Introduces a CalendarCancellation flag similar to the +QMailMessage::CalendarInvitation to be matched against the +QMailMessage::status() bitfield. + +While the CalendarInvitation flag indicates that the message contains an +attachment of type text/calendar with "REQUEST" method, the +CalendarCancellation flag indicates that there's an attachment of type +text/calendar with "CANCEL" method type. In other words, a calendar +event cancellation. + +For reference, the "CANCEL" method of the Content Type header is +described in RFC2447 (iMIP) Section 2.4 [1] in combination with the +RFC2446 (iTIP) sections 3.2 and 3.2.5 [2] + +[1] https://tools.ietf.org/html/rfc2447#section-2.4 +[2] https://tools.ietf.org/html/rfc2446#section-3.2 +--- + examples/qtmail/browserwidget.cpp | 1 + + src/libraries/qmfclient/qmailmessage.cpp | 31 +++++++++++++++++-- + src/libraries/qmfclient/qmailmessage.h | 3 ++ + src/libraries/qmfclient/qmailstore_p.cpp | 4 ++- + .../messageservices/imap/imapclient.cpp | 3 +- + .../messageservices/imap/imapstrategy.cpp | 1 + + src/plugins/messageservices/pop/popclient.cpp | 1 + + 7 files changed, 39 insertions(+), 5 deletions(-) + +diff --git a/examples/qtmail/browserwidget.cpp b/examples/qtmail/browserwidget.cpp +index 69eb62ce..3a2775b9 100644 +--- a/examples/qtmail/browserwidget.cpp ++++ b/examples/qtmail/browserwidget.cpp +@@ -814,6 +814,7 @@ void BrowserWidget::displayHtml(const QMailMessage* mail) + + metadata.append(qMakePair(tr("Message Id"), QString::number(mail->id().toULongLong()))); + metadata.append(qMakePair(tr("CalendarInvitation"), (mail->status() & QMailMessage::CalendarInvitation) ? QString("true") : QString("false"))); ++ metadata.append(qMakePair(tr("CalendarCancellation"), (mail->status() & QMailMessage::CalendarCancellation) ? QString("true") : QString("false"))); + + if ( (mail->status() & QMailMessage::Incoming) && + !(mail->status() & QMailMessage::PartialContentAvailable) ) { +diff --git a/src/libraries/qmfclient/qmailmessage.cpp b/src/libraries/qmfclient/qmailmessage.cpp +index ecfe9d41..f4255dee 100644 +--- a/src/libraries/qmfclient/qmailmessage.cpp ++++ b/src/libraries/qmfclient/qmailmessage.cpp +@@ -6531,7 +6531,7 @@ static quint64 lowPriorityFlag = 0; + static quint64 calendarInvitationFlag = 0; + static quint64 todoFlag = 0; + static quint64 noNotificationFlag = 0; +- ++static quint64 calendarCancellationFlag = 0; + + /* QMailMessageMetaData */ + +@@ -7177,6 +7177,15 @@ void QMailMessageMetaDataPrivate::deserialize(Stream &stream) + message externalized by saving in a drafts or sent folder. + */ + ++/*! ++ \variable QMailMessageMetaData::CalendarCancellation ++ ++ The status mask needed for testing the value of the registered status flag named ++ \c "CalendarCancellation" against the result of QMailMessage::status(). ++ ++ This flag indicates that the message includes a calendar invitation cancel part. ++*/ ++ + const quint64 &QMailMessageMetaData::Incoming = incomingFlag; + const quint64 &QMailMessageMetaData::Outgoing = outgoingFlag; + const quint64 &QMailMessageMetaData::Sent = sentFlag; +@@ -7209,6 +7218,7 @@ const quint64 &QMailMessageMetaData::LowPriority = lowPriorityFlag; + const quint64 &QMailMessageMetaData::CalendarInvitation = calendarInvitationFlag; + const quint64 &QMailMessageMetaData::Todo = todoFlag; + const quint64 &QMailMessageMetaData::NoNotification = noNotificationFlag; ++const quint64 &QMailMessageMetaData::CalendarCancellation = calendarCancellationFlag; + + /*! + Constructs an empty message meta data object. +@@ -8594,6 +8604,21 @@ bool QMailMessage::contentModified() const + otherwise returns false. + */ + bool QMailMessage::hasCalendarInvitation() const ++{ ++ return hasCalendarMethod("request"); ++} ++ ++/*! ++ Returns true if the message contains a calendar cancellation; ++ otherwise returns false. ++*/ ++bool QMailMessage::hasCalendarCancellation() const ++{ ++ return hasCalendarMethod("cancel"); ++} ++ ++/*! \internal */ ++bool QMailMessage::hasCalendarMethod(QByteArray const &method) const + { + QList parts; + parts.append(this); +@@ -8602,12 +8627,12 @@ bool QMailMessage::hasCalendarInvitation() const + const QMailMessagePartContainer *part(parts.takeFirst()); + if (part->multipartType() != QMailMessagePartContainer::MultipartNone) { + for (uint i = 0; i < part->partCount(); ++i) { +- parts.append(&part->partAt(i)); ++ parts.append(&part->partAt(i)); + } + } else { + const QMailMessageContentType &ct(part->contentType()); + if (ct.matches("text", "calendar") && +- (ct.parameter("method").toLower() == "request")) { ++ (ct.parameter("method").toLower() == method.toLower())) { + return true; + } + } +diff --git a/src/libraries/qmfclient/qmailmessage.h b/src/libraries/qmfclient/qmailmessage.h +index 46f6199b..9f4fe1d8 100644 +--- a/src/libraries/qmfclient/qmailmessage.h ++++ b/src/libraries/qmfclient/qmailmessage.h +@@ -582,6 +582,7 @@ public: + static const quint64 &CalendarInvitation; + static const quint64 &Todo; + static const quint64 &NoNotification; ++ static const quint64 &CalendarCancellation; + + QMailMessageMetaData(); + #ifndef QTOPIAMAIL_PARSING_ONLY +@@ -793,6 +794,7 @@ public: + virtual bool partialContentAvailable() const; + + virtual bool hasCalendarInvitation() const; ++ virtual bool hasCalendarCancellation() const; + + virtual bool contentModified() const; + +@@ -812,6 +814,7 @@ private: + QMailMessagePrivate* partContainerImpl(); + const QMailMessagePrivate* partContainerImpl() const; + ++ virtual bool hasCalendarMethod(QByteArray const &method) const; + virtual void setUnmodified(); + + QByteArray duplicatedData(const QString&) const; +diff --git a/src/libraries/qmfclient/qmailstore_p.cpp b/src/libraries/qmfclient/qmailstore_p.cpp +index d21a7e19..7f0e01d0 100644 +--- a/src/libraries/qmfclient/qmailstore_p.cpp ++++ b/src/libraries/qmfclient/qmailstore_p.cpp +@@ -3230,7 +3230,9 @@ bool QMailStorePrivate::initStore() + || attemptRegisterStatusBit(QLatin1String("UseCryptoSignatureByDefault"), QLatin1String("accountstatus"), + 63, true, const_cast(&QMailAccount::UseCryptoSignatureByDefault), t, false) + || attemptRegisterStatusBit(QLatin1String("NoNotification"), QLatin1String("messagestatus"), +- 63, true, const_cast(&QMailMessage::NoNotification), t, false); ++ 63, true, const_cast(&QMailMessage::NoNotification), t, false) ++ || attemptRegisterStatusBit(QLatin1String("CalendarCancellation"), QLatin1String("messagestatus"), ++ 63, true, const_cast(&QMailMessage::CalendarCancellation), t, false); + + if (res) { + qWarning() << "There was an error registering flags."; +diff --git a/src/plugins/messageservices/imap/imapclient.cpp b/src/plugins/messageservices/imap/imapclient.cpp +index cfb11519..2ed9f5ed 100644 +--- a/src/plugins/messageservices/imap/imapclient.cpp ++++ b/src/plugins/messageservices/imap/imapclient.cpp +@@ -1036,7 +1036,8 @@ void ImapClient::messageFetched(QMailMessage& mail, const QString &detachedFilen + } + mail.setStatus(QMailMessage::CalendarInvitation, mail.hasCalendarInvitation()); + mail.setStatus(QMailMessage::HasSignature, (QMailCryptographicServiceFactory::findSignedContainer(&mail) != 0)); +- ++ mail.setStatus(QMailMessage::CalendarCancellation, mail.hasCalendarCancellation()); ++ + // Disable Notification when getting older message + QMailFolder folder(properties.id); + bool ok1, ok2; // toUint returns 0 on error, which is an invalid IMAP uid +diff --git a/src/plugins/messageservices/imap/imapstrategy.cpp b/src/plugins/messageservices/imap/imapstrategy.cpp +index 7511336b..1198c60d 100644 +--- a/src/plugins/messageservices/imap/imapstrategy.cpp ++++ b/src/plugins/messageservices/imap/imapstrategy.cpp +@@ -4286,6 +4286,7 @@ void ImapCopyMessagesStrategy::updateCopiedMessage(ImapStrategyContextBase *, QM + message.setStatus(QMailMessage::Sent, source.status() & QMailMessage::Sent); + message.setStatus(QMailMessage::Junk, source.status() & QMailMessage::Junk); + message.setStatus(QMailMessage::CalendarInvitation, source.hasCalendarInvitation()); ++ message.setStatus(QMailMessage::CalendarCancellation, source.hasCalendarCancellation()); + + // Need to set content scheme and identifier to prevent file leaks + message.setContentScheme(source.contentScheme()); +diff --git a/src/plugins/messageservices/pop/popclient.cpp b/src/plugins/messageservices/pop/popclient.cpp +index f44528fd..b4f64d91 100644 +--- a/src/plugins/messageservices/pop/popclient.cpp ++++ b/src/plugins/messageservices/pop/popclient.cpp +@@ -1235,6 +1235,7 @@ void PopClient::createMail() + } + mail->setStatus(QMailMessage::CalendarInvitation, mail->hasCalendarInvitation()); + mail->setStatus(QMailMessage::HasAttachments, mail->hasAttachments()); ++ mail->setStatus(QMailMessage::CalendarCancellation, mail->hasCalendarCancellation()); + } + + // Special case to handle spurious hotmail messages. Hide in UI, but do not delete from server +-- +2.26.2 + diff --git a/rpm/qmf-qt5.spec b/rpm/qmf-qt5.spec index 7c931ae..5062c4d 100644 --- a/rpm/qmf-qt5.spec +++ b/rpm/qmf-qt5.spec @@ -1,6 +1,6 @@ Name: qmf-qt5 Summary: Qt Messaging Framework (QMF) Qt5 -Version: 4.0.4+git63 +Version: 4.0.4+git126 Release: 1 License: LGPLv2.1 with exception or GPLv3 URL: https://code.qt.io/qt-labs/messagingframework.git @@ -57,6 +57,7 @@ Patch25: 0025-Add-missing-slash-character-as-protected-in-header-p.patch Patch26: 0026-Handle-encoded-word-s-containing-partial-characters.patch Patch27: 0027-Allow-a-service-provided-folder-to-be-set-as-the-sta.patch Patch28: 0028-Use-a-queued-connection-to-handle-accountsUpdated-si.patch +Patch29: 0029-Add-QMailMessage-CalendarCancellation-flag.patch %description The Qt Messaging Framework, QMF, consists of a C++ library and daemon server