/* * Copyright (c) 2010 Mark Liversedge (liversedge@gmail.com) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ICalendar.h" #include "GcCalendarModel.h" #include "CalendarDownload.h" #include void ICalendar::setICalendarProperties() { #if 0 // keeping it for later, we will eventually use this // commented out to reduce compiler warnings static struct { icalproperty_kind type; QString friendly; } ICalendarProperties[] = { { ICAL_ACTION_PROPERTY, tr("Action") }, { ICAL_ALLOWCONFLICT_PROPERTY, tr("Allow Conflict") }, { ICAL_ATTACH_PROPERTY, tr("Attachment") }, { ICAL_ATTENDEE_PROPERTY, tr("Attendee") }, { ICAL_CALID_PROPERTY, tr("Calendar Identifier") }, { ICAL_CALMASTER_PROPERTY, tr("Master") }, { ICAL_CALSCALE_PROPERTY, tr("Scale") }, { ICAL_CAPVERSION_PROPERTY, tr("Version") }, { ICAL_CARLEVEL_PROPERTY, tr("Level") }, { ICAL_CARID_PROPERTY, tr("Event Identifier") }, { ICAL_CATEGORIES_PROPERTY, tr("Category") }, { ICAL_CLASS_PROPERTY, tr("Class") }, { ICAL_CMD_PROPERTY, tr("Command") }, { ICAL_COMMENT_PROPERTY, tr("Comment") }, { ICAL_COMPLETED_PROPERTY, tr("Completed") }, { ICAL_COMPONENTS_PROPERTY, tr("") }, { ICAL_CONTACT_PROPERTY, tr("Contact") }, { ICAL_CREATED_PROPERTY, tr("Date Created") }, { ICAL_CSID_PROPERTY, tr("CSID?") }, { ICAL_DATEMAX_PROPERTY, tr("No later than") }, { ICAL_DATEMIN_PROPERTY, tr("No earlier than") }, { ICAL_DECREED_PROPERTY, tr("Decreed") }, { ICAL_DEFAULTCHARSET_PROPERTY, tr("Default character set") }, { ICAL_DEFAULTLOCALE_PROPERTY, tr("Default locale") }, { ICAL_DEFAULTTZID_PROPERTY, tr("Default timezone") }, { ICAL_DEFAULTVCARS_PROPERTY, tr("Default VCar") }, { ICAL_DENY_PROPERTY, tr("Deny") }, { ICAL_DESCRIPTION_PROPERTY, tr("Description") }, { ICAL_DTEND_PROPERTY, tr("End Date & Time") }, { ICAL_DTSTAMP_PROPERTY, tr("Timestamp") }, { ICAL_DTSTART_PROPERTY, tr("Start Date & Time") }, { ICAL_DUE_PROPERTY, tr("Due Date") }, { ICAL_DURATION_PROPERTY, tr("Duration") }, { ICAL_EXDATE_PROPERTY, tr("Expiry Date") }, { ICAL_EXPAND_PROPERTY, tr("Expand") }, { ICAL_EXRULE_PROPERTY, tr("Exclusive rule") }, { ICAL_FREEBUSY_PROPERTY, tr("Freebusy") }, { ICAL_GEO_PROPERTY, tr("Geo") }, { ICAL_GRANT_PROPERTY, tr("Grant") }, { ICAL_ITIPVERSION_PROPERTY, tr("ITIP Version") }, { ICAL_LASTMODIFIED_PROPERTY, tr("Modified Date") }, { ICAL_LOCATION_PROPERTY, tr("Location") }, { ICAL_MAXCOMPONENTSIZE_PROPERTY, tr("Max component size") }, { ICAL_MAXDATE_PROPERTY, tr("No later than") }, { ICAL_MAXRESULTS_PROPERTY, tr("Maximum results") }, { ICAL_MAXRESULTSSIZE_PROPERTY, tr("Maximum results size") }, { ICAL_METHOD_PROPERTY, tr("Method") }, { ICAL_MINDATE_PROPERTY, tr("Np earlier than") }, { ICAL_MULTIPART_PROPERTY, tr("Is Multipart") }, { ICAL_NAME_PROPERTY, tr("Name") }, { ICAL_ORGANIZER_PROPERTY, tr("Organised by") }, { ICAL_OWNER_PROPERTY, tr("Owner") }, { ICAL_PERCENTCOMPLETE_PROPERTY, tr("Percent Complete") }, { ICAL_PERMISSION_PROPERTY, tr("Permissions") }, { ICAL_PRIORITY_PROPERTY, tr("Priority") }, { ICAL_PRODID_PROPERTY, tr("Prod Identifier") }, { ICAL_QUERY_PROPERTY, tr("Query") }, { ICAL_QUERYLEVEL_PROPERTY, tr("Query Level") }, { ICAL_QUERYID_PROPERTY, tr("Query Identifier") }, { ICAL_QUERYNAME_PROPERTY, tr("Query Name") }, { ICAL_RDATE_PROPERTY, tr("Recurring Date") }, { ICAL_RECURACCEPTED_PROPERTY, tr("Recurring Accepted") }, { ICAL_RECUREXPAND_PROPERTY, tr("Recurring Expanded") }, { ICAL_RECURLIMIT_PROPERTY, tr("Recur no later than") }, { ICAL_RECURRENCEID_PROPERTY, tr("Reccurrence Identifier") }, { ICAL_RELATEDTO_PROPERTY, tr("Related to") }, { ICAL_RELCALID_PROPERTY, tr("Related to Calendar Identifier") }, { ICAL_REPEAT_PROPERTY, tr("Repeat") }, { ICAL_REQUESTSTATUS_PROPERTY, tr("Request Status") }, { ICAL_RESOURCES_PROPERTY, tr("Resources") }, { ICAL_RESTRICTION_PROPERTY, tr("Restriction") }, { ICAL_RRULE_PROPERTY, tr("Rule") }, { ICAL_SCOPE_PROPERTY, tr("Scope") }, { ICAL_SEQUENCE_PROPERTY, tr("Sequence Number") }, { ICAL_STATUS_PROPERTY, tr("Status") }, { ICAL_STORESEXPANDED_PROPERTY, tr("Stores Expanded") }, { ICAL_SUMMARY_PROPERTY, tr("Summary") }, { ICAL_TARGET_PROPERTY, tr("Target") }, { ICAL_TRANSP_PROPERTY, tr("Transport") }, { ICAL_TRIGGER_PROPERTY, tr("Trigger") }, { ICAL_TZID_PROPERTY, tr("Timezone Identifier") }, { ICAL_TZNAME_PROPERTY, tr("Timezone Name") }, { ICAL_TZOFFSETFROM_PROPERTY, tr("Timezone Offset from") }, { ICAL_TZOFFSETTO_PROPERTY, tr("Timezone Offset to") }, { ICAL_TZURL_PROPERTY, tr("Timezone URL") }, { ICAL_UID_PROPERTY, tr("Unique Identifier") }, { ICAL_URL_PROPERTY, tr("URL") }, { ICAL_VERSION_PROPERTY, tr("Version") }, { ICAL_X_PROPERTY, tr("X-Property") }, { ICAL_XLICCLASS_PROPERTY, tr("XLI Class") }, { ICAL_XLICCLUSTERCOUNT_PROPERTY, tr("XLI Cluster count") }, { ICAL_XLICERROR_PROPERTY, tr("XLI error") }, { ICAL_XLICMIMECHARSET_PROPERTY, tr("XLI mime character set") }, { ICAL_XLICMIMECID_PROPERTY, tr("XLI mime class Identifier") }, { ICAL_XLICMIMECONTENTTYPE_PROPERTY, tr("XLI mime content type") }, { ICAL_XLICMIMEENCODING_PROPERTY, tr("XLI mime encoding") }, { ICAL_XLICMIMEFILENAME_PROPERTY, tr("XLI mime filename") }, { ICAL_XLICMIMEOPTINFO_PROPERTY, tr("XLI mime optional information") }, { ICAL_NO_PROPERTY, tr("") } // ICAL_NO_PROPERTY must always be last!! }; #endif } // convert property to a string static QString propertyToString(icalproperty *p) { if (p) { icalvalue *v = icalproperty_get_value(p); QString converted(icalvalue_as_ical_string(v)); // some special characters are escaped in the text converted.replace("\\n", "\n"); converted.replace("\\;", ";"); return converted; } else { return QString(""); } } // convert property to a DateTime static QDateTime propertyToDate(icalproperty *p) { if (p) { icalvalue *v = icalproperty_get_value(p); struct icaltimetype date = icalvalue_get_datetime(v); QDateTime when(QDate(date.year, date.month, date.day), QTime(date.hour, date.minute, date.second)); return when; } else { return QDateTime(); } } ICalendar::ICalendar(MainWindow *parent) : QWidget(parent), main(parent) { // get from local and remote calendar // local file QString localFilename = main->home.absolutePath()+"/calendar.ics"; QFile localFile(localFilename); if (localFile.exists() && localFile.open(QFile::ReadOnly | QFile::Text)) { // read in the whole thing QTextStream in(&localFile); QString fulltext = in.readAll(); localFile.close(); // parse parse(fulltext, localCalendar); } // remote file main->calendarDownload->download(); } void ICalendar::refreshRemote(QString fulltext) { parse(fulltext, remoteCalendar); } void ICalendar::parse(QString fulltext, QMap*>&calendar) { // parse the contents using libical icalcomponent *root = icalparser_parse_string(fulltext.toLatin1().constData()); clearCalendar(calendar,false); if (root) { // iterate over events (not interested in the rest for now) //for (icalcomponent *c = icalcomponent_get_first_component(root, ICAL_VEVENT_COMPONENT); for (icalcomponent *event = icalcomponent_get_first_component(root, ICAL_VEVENT_COMPONENT); event != NULL; event = icalcomponent_get_next_component(root, ICAL_VEVENT_COMPONENT)) { // Get start date... icalproperty *date = icalcomponent_get_first_property(event, ICAL_DTSTART_PROPERTY); if (date) { // ignore events with no date! QDate startDate = propertyToDate(date).date(); QList* events = calendar.value(startDate, NULL); if (!events) { events = new QList; calendar.insert(startDate, events); } events->append(event); } } } emit dataChanged(); } void ICalendar::clearCalendar(QMap*>&calendar, bool signal) { QMapIterator* >i(calendar); while (i.hasNext()) { i.next(); delete i.value(); } calendar.clear(); if (signal) emit dataChanged(); } // for models to pass straight through to access and // set the calendar data QVariant ICalendar::data(QDate date, int role) { switch (role) { case GcCalendarModel::EventCountRole: { int count = 0; QList*p = localCalendar.value(date, NULL); if (p) count += p->count(); p = remoteCalendar.value(date, NULL); if (p) count += p->count(); return count; } case Qt::DisplayRole: // returns a list for the given date case Qt::EditRole: // returns a list for the given date { QStringList strings; // local QList*p = localCalendar.value(date, NULL); if (p) { foreach(icalcomponent*event, *p) { QString desc; icalproperty *summary = icalcomponent_get_first_property(event, ICAL_SUMMARY_PROPERTY); desc = propertyToString(summary); icalproperty *property = icalcomponent_get_first_property(event, ICAL_DESCRIPTION_PROPERTY); desc += " "; desc += propertyToString(property); strings << desc; } } // remote p = remoteCalendar.value(date, NULL); if (p) { foreach(icalcomponent*event, *p) { QString desc; icalproperty *summary = icalcomponent_get_first_property(event, ICAL_SUMMARY_PROPERTY); desc = propertyToString(summary); icalproperty *property = icalcomponent_get_first_property(event, ICAL_DESCRIPTION_PROPERTY); desc += " "; desc += propertyToString(property); strings << desc; } } return strings; } break; default: break; } return QVariant(); }