Ejemplo n.º 1
0
bool GoogleCalHandler::startElement( const QString & namespaceURI, const QString & localName, const QString & qName, const QXmlAttributes & atts )
{
    Q_UNUSED(namespaceURI);
    Q_UNUSED(localName);

    // if we are in a tree we dont' recognize, ignore the lot of it.
    if (ignoreDepth) {
        ignoreDepth++;
        return true;
    }

    Element t = token(qName);
    switch(t) {
        case Entry:
            state = EntryState;
            break;
        case Feed:
            state = FeedState;
            break;
        case Category:
            if (atts.value("scheme").endsWith("#kind")
                    && atts.value("term").endsWith("#event"))
                state = EventState;
            // TODO other kinds of categories?
            break;
        case Status:
            // this is how deleted events are detected
            if (atts.value("value").endsWith("#event.canceled"))  {
                removeCurrentAppointment = true;
            }
            break;
        case Reminder:
            if (!atts.value("minutes").isEmpty()) {
                lastAppointment.setAlarm(atts.value("minutes").toInt(), QAppointment::Visible);
            } else if (!atts.value("hours").isEmpty()) {
                lastAppointment.setAlarm(atts.value("minutes").toInt()*60, QAppointment::Visible);
            }
            // TODO doesn't handle days or absolute time.
            break;
        case When:
            {
                QString st = atts.value("startTime");
                QString et = atts.value("endTime");
                if (st.isEmpty() || et.isEmpty()) {
                    ignoreDepth++;
                } else {
                    QTimeZone tz = parseTimeZone(st);
                    QDateTime start = parseDateTime(st, tz);
                    QDateTime end = parseDateTime(et, tz);
                    if (st.length() < 19)
                        lastAppointment.setAllDay(true);
                    lastAppointment.setTimeZone(tz);
                    lastAppointment.setStart(start);
                    lastAppointment.setEnd(end);
                }
            }
            break;
        case Where:
            lastAppointment.setLocation(atts.value("valueString"));
            break;
        case Title:
        case Content:
            if (atts.value("type") != "text") {
                ignoreDepth++;
            }
            break;
        case Recurrence:
        case Id:
        case Published:
        case Updated:
            if (state != EntryState && state != EventState) {
                ignoreDepth++;
                break;
            }
            break;
        case Unrecognized:
            ignoreDepth++;
    }
    return true;
}
Ejemplo n.º 2
0
bool GoogleCalHandler::endElement( const QString & namespaceURI, const QString & localName, const QString & qName )
{
    Q_UNUSED(namespaceURI);
    Q_UNUSED(localName);

    if (ignoreDepth) {
        ignoreDepth--;
        Q_ASSERT(ignoreDepth >= 0);
        return true;
    }
    Element t = token(qName);
    switch(t) {
        case Entry:
            if (removeCurrentAppointment) {
                mRemoved.append(lastAppointment.uid());
                removeCurrentAppointment = false;
            } else {
                mAppointments.append(lastAppointment);
            }
            lastAppointment = QAppointment();
            state = FeedState;
            break;
        case Feed:
            state = StartState;
        case Title:
            if (state == FeedState)
                mName = lastText;
            else
                lastAppointment.setDescription(lastText);
            break;
        case Content:
            lastAppointment.setNotes(lastText);
            break;
        case Recurrence:
            {
            // this is the MAIN TODO, seeing as once this works,
                /*
                   iCal format, is not compatible with vcard parsing.
                   however it may be similar enough that we can still use existing vcard
                   parser.

                   NOTE: RRULE format is different in iCal to vCard
               */
            /* Example RRULE text from recurrence section.
               can be given instead of when
               e.g.
                DTSTART;TZID=Australia/Brisbane:20060615T113000
                DURATION:PT1800S
                RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TH

                BEGIN:VTIMEZONE
                TZID:Australia/Brisbane
                X-LIC-LOCATION:Australia/Brisbane
                BEGIN:STANDARD
                TZOFFSETFROM:+1000
                TZOFFSETTO:+1000
                TZNAME:EST
                DTSTART:19700101T000000
                END:STANDARD
                END:VTIMEZONE
             */

                // pad out data to make it look like a vcal and get through our parser
                // qappointment also has some special ical handling in it.
                QByteArray data = "BEGIN:VCALENDAR\r\nVERSION:1.0\r\nBEGIN:VEVENT\r\n"
                    + lastText.toUtf8() + "END:VEVENT\r\nEND:VCALENDAR\r\n";

                QList<QAppointment> result = QAppointment::readVCalendarData(data.constData(), data.length());
                if (result.count() > 0) {
                    QAppointment a = result[0];
                    lastAppointment.setStart(a.start());
                    lastAppointment.setEnd(a.end());
                    lastAppointment.setRepeatRule(a.repeatRule());
                    lastAppointment.setFrequency(a.frequency());
                    lastAppointment.setRepeatUntil(a.repeatUntil());
                    lastAppointment.setWeekFlags(a.weekFlags());
                }
            }
            break;
        case Id:
            {
                QUniqueId u = parseId(lastText + mIdContext);
                lastAppointment.setUid(u);
                // a lot more redundency in a google id.
                lastAppointment.setCustomField("GoogleId", lastText);
            }
            break;
        case Published:
            {
                // TODO should support published/updated fields natively in PimRecords?
                QDateTime dt = parseDateTime(lastText, QTimeZone::utc());
                lastAppointment.setCustomField("GooglePublished", dt.toString(Qt::ISODate));
            }
            break;
        case Updated:
            {
                QDateTime dt = parseDateTime(lastText, QTimeZone::utc());
                lastAppointment.setCustomField("GoogleUpdated", dt.toString(Qt::ISODate));
            }
            break;
        case Category:
        case Reminder:
        case When:
        case Where:
        case Status:
            break;
        case Unrecognized:
            break;

    }
    return true;
}