Commit a5614748 authored by Damien Caliste's avatar Damien Caliste

Re-add COLOR property serialization from RFC7986.

This is re-adding parsing for color property, but with
conditional compilation since this property is supported
only from libical >= 3.0.0.
parent feaa3ddf
......@@ -20,6 +20,80 @@ QTEST_MAIN(ICalFormatTest)
using namespace KCalendarCore;
void ICalFormatTest::testDeserializeSerialize()
{
ICalFormat format;
const QString serializedCalendar
= QLatin1String("BEGIN:VCALENDAR\n"
"PRODID:-//IDN nextcloud.com//Calendar app 2.0.4//EN\n"
"VERSION:2.0\n"
"BEGIN:VEVENT\n"
"CREATED:20201103T161248Z\n"
"DTSTAMP:20201103T161340Z\n"
"LAST-MODIFIED:20201103T161340Z\n"
"SEQUENCE:2\n"
"UID:bd1d299d-3b03-4514-be69-e680ad2ff884\n"
"DTSTART;TZID=Europe/Paris:20201103T100000\n"
"DTEND;TZID=Europe/Paris:20201103T110000\n"
"SUMMARY:test recur\n"
"RRULE:FREQ=DAILY;COUNT=4\n"
"END:VEVENT\n"
"BEGIN:VEVENT\n"
"CREATED:20201103T161823Z\n"
"DTSTAMP:20201103T161823Z\n"
"LAST-MODIFIED:20201103T161823Z\n"
"SEQUENCE:1\n"
"UID:bd1d299d-3b03-4514-be69-e680ad2ff884\n"
"DTSTART;TZID=Europe/Paris:20201104T111500\n"
"DTEND;TZID=Europe/Paris:20201104T121500\n"
"SUMMARY:test recur\n"
"COLOR:khaki\n"
"RECURRENCE-ID;TZID=Europe/Paris:20201104T100000\n"
"END:VEVENT\n"
"END:VCALENDAR");
MemoryCalendar::Ptr calendar = MemoryCalendar::Ptr(new MemoryCalendar(QTimeZone::utc()));
QVERIFY(format.fromString(calendar, serializedCalendar));
const QString uid = QString::fromLatin1("bd1d299d-3b03-4514-be69-e680ad2ff884");
Incidence::Ptr parent = calendar->incidence(uid);
QVERIFY(parent);
const QDateTime start(QDate(2020, 11, 3), QTime(9,0), QTimeZone::utc());
QCOMPARE(parent->dtStart(), start);
QCOMPARE(parent.staticCast<Event>()->dtEnd(), start.addSecs(3600));
QCOMPARE(parent->summary(), QString::fromLatin1("test recur"));
QCOMPARE(parent->revision(), 2);
Recurrence *recur = parent->recurrence();
QVERIFY(recur->recurs());
QCOMPARE(recur->duration(), 4);
QCOMPARE(recur->recurrenceType(), static_cast<ushort>(Recurrence::rDaily));
Incidence::Ptr occurrence = calendar->incidence(uid, start.addDays(1));
QVERIFY(occurrence);
const QDateTime startOcc(QDate(2020, 11, 4), QTime(10,15), QTimeZone::utc());
QCOMPARE(occurrence->dtStart(), startOcc);
QCOMPARE(occurrence.staticCast<Event>()->dtEnd(), startOcc.addSecs(3600));
#if defined(USE_ICAL_3)
QCOMPARE(occurrence->color(), QString::fromLatin1("khaki"));
#else
QVERIFY(occurrence->color().isEmpty());
#endif
QCOMPARE(occurrence->summary(), QString::fromLatin1("test recur"));
QCOMPARE(occurrence->revision(), 1);
QVERIFY(occurrence->hasRecurrenceId());
QCOMPARE(occurrence->recurrenceId(), start.addDays(1));
const QString serialization = format.toString(calendar, QString());
QVERIFY(!serialization.isEmpty());
MemoryCalendar::Ptr check = MemoryCalendar::Ptr(new MemoryCalendar(QTimeZone::utc()));
QVERIFY(format.fromString(check, serialization));
Incidence::Ptr reparent = check->incidence(uid);
QVERIFY(reparent);
QCOMPARE(*parent, *reparent);
Incidence::Ptr reoccurence = check->incidence(uid, start.addDays(1));
QVERIFY(reoccurence);
QCOMPARE(*occurrence, *reoccurence);
}
void ICalFormatTest::testCharsets()
{
ICalFormat format;
......
......@@ -16,6 +16,7 @@ class ICalFormatTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testDeserializeSerialize();
void testCharsets();
void testVolatileProperties();
void testCuType();
......
......@@ -530,6 +530,14 @@ void ICalFormatImpl::writeIncidence(icalcomponent *parent,
icalcomponent_add_property(parent, icalproperty_new_class(secClass));
}
#if defined(USE_ICAL_3)
// color
if (!incidence->color().isEmpty()) {
icalcomponent_add_property(
parent, icalproperty_new_color(incidence->color().toUtf8().constData()));
}
#endif
// geo
if (incidence->hasGeo()) {
icalgeotype geo;
......@@ -1901,6 +1909,12 @@ void ICalFormatImpl::readIncidence(icalcomponent *parent, const Incidence::Ptr &
incidence->addAttachment(readAttachment(p));
break;
#if defined(USE_ICAL_3)
case ICAL_COLOR_PROPERTY:
incidence->setColor(QString::fromUtf8(icalproperty_get_color(p)));
break;
#endif
default:
// TODO: do something about unknown properties?
break;
......
......@@ -74,6 +74,7 @@ public:
, mPriority(p.mPriority)
, mStatus(p.mStatus)
, mSecrecy(p.mSecrecy)
, mColor(p.mColor)
, mDescriptionIsRich(p.mDescriptionIsRich)
, mSummaryIsRich(p.mSummaryIsRich)
, mLocationIsRich(p.mLocationIsRich)
......@@ -153,6 +154,7 @@ public:
int mPriority; // priority: 1 = highest, 2 = less, etc.
Status mStatus; // status
Secrecy mSecrecy; // secrecy
QString mColor; // background color
bool mDescriptionIsRich = false; // description string is richtext.
bool mSummaryIsRich = false; // summary string is richtext.
bool mLocationIsRich = false; // location string is richtext.
......@@ -287,6 +289,7 @@ bool Incidence::equals(const IncidenceBase &incidence) const
&& secrecy() == i2->secrecy()
&& priority() == i2->priority()
&& stringCompare(location(), i2->location())
&& stringCompare(color(), i2->color())
&& stringCompare(schedulingID(), i2->schedulingID())
&& recurrenceId() == i2->recurrenceId()
&& conferences() == i2->conferences()
......@@ -546,6 +549,24 @@ QString Incidence::relatedTo(RelType relType) const
return d->mRelatedToUid.value(relType);
}
void Incidence::setColor(const QString &colorName)
{
if (mReadOnly) {
return;
}
if (!stringCompare(d->mColor, colorName)) {
update();
d->mColor = colorName;
setFieldDirty(FieldColor);
updated();
}
}
QString Incidence::color() const
{
return d->mColor;
}
// %%%%%%%%%%%% Recurrence-related methods %%%%%%%%%%%%%%%%%%%%
Recurrence *Incidence::recurrence() const
......
......@@ -399,6 +399,22 @@ public:
*/
Q_REQUIRED_RESULT QString relatedTo(RelType relType = RelTypeParent) const;
/**
Set the incidence color, as added in RFC7986.
@param colorName a named color as defined in CSS3 color name, see
https://www.w3.org/TR/css-color-3/#svg-color.
@since: 5.76
*/
void setColor(const QString &colorName);
/**
Returns the color, if any is defined, for this incidence.
@since: 5.76
*/
Q_REQUIRED_RESULT QString color() const;
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%% Convenience wrappers for property handling
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......
......@@ -186,7 +186,8 @@ public:
FieldUid, ///> Field representing the UID component.
FieldUnknown, ///> Something changed. Always set when you use the assignment operator.
FieldUrl, ///> Field representing the URL component.
FieldConferences ///> Field representing the CONFERENCE component.
FieldConferences, ///> Field representing the CONFERENCE component.
FieldColor ///> Field representing the COLOR component.
};
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment