Search in sources :

Example 1 with EventRecurrence

use of com.android.calendarcommon2.EventRecurrence in project Etar-Calendar by Etar-Group.

the class EditEventHelper method updateRecurrenceRule.

/**
     * Uses the recurrence selection and the model data to build an rrule and
     * write it to the model.
     *
     * @param selection the type of rrule
     * @param model The event to update
     * @param weekStart the week start day, specified as java.util.Calendar
     * constants
     */
static void updateRecurrenceRule(int selection, CalendarEventModel model, int weekStart) {
    // Make sure we don't have any leftover data from the previous setting
    EventRecurrence eventRecurrence = new EventRecurrence();
    if (selection == DOES_NOT_REPEAT) {
        model.mRrule = null;
        return;
    } else if (selection == REPEATS_CUSTOM) {
        // Keep custom recurrence as before.
        return;
    } else if (selection == REPEATS_DAILY) {
        eventRecurrence.freq = EventRecurrence.DAILY;
    } else if (selection == REPEATS_EVERY_WEEKDAY) {
        eventRecurrence.freq = EventRecurrence.WEEKLY;
        int dayCount = 5;
        int[] byday = new int[dayCount];
        int[] bydayNum = new int[dayCount];
        byday[0] = EventRecurrence.MO;
        byday[1] = EventRecurrence.TU;
        byday[2] = EventRecurrence.WE;
        byday[3] = EventRecurrence.TH;
        byday[4] = EventRecurrence.FR;
        for (int day = 0; day < dayCount; day++) {
            bydayNum[day] = 0;
        }
        eventRecurrence.byday = byday;
        eventRecurrence.bydayNum = bydayNum;
        eventRecurrence.bydayCount = dayCount;
    } else if (selection == REPEATS_WEEKLY_ON_DAY) {
        eventRecurrence.freq = EventRecurrence.WEEKLY;
        int[] days = new int[1];
        int dayCount = 1;
        int[] dayNum = new int[dayCount];
        Time startTime = new Time(model.mTimezone);
        startTime.set(model.mStart);
        days[0] = EventRecurrence.timeDay2Day(startTime.weekDay);
        // not sure why this needs to be zero, but set it for now.
        dayNum[0] = 0;
        eventRecurrence.byday = days;
        eventRecurrence.bydayNum = dayNum;
        eventRecurrence.bydayCount = dayCount;
    } else if (selection == REPEATS_MONTHLY_ON_DAY) {
        eventRecurrence.freq = EventRecurrence.MONTHLY;
        eventRecurrence.bydayCount = 0;
        eventRecurrence.bymonthdayCount = 1;
        int[] bymonthday = new int[1];
        Time startTime = new Time(model.mTimezone);
        startTime.set(model.mStart);
        bymonthday[0] = startTime.monthDay;
        eventRecurrence.bymonthday = bymonthday;
    } else if (selection == REPEATS_MONTHLY_ON_DAY_COUNT) {
        eventRecurrence.freq = EventRecurrence.MONTHLY;
        eventRecurrence.bydayCount = 1;
        eventRecurrence.bymonthdayCount = 0;
        int[] byday = new int[1];
        int[] bydayNum = new int[1];
        Time startTime = new Time(model.mTimezone);
        startTime.set(model.mStart);
        // Compute the week number (for example, the "2nd" Monday)
        int dayCount = 1 + ((startTime.monthDay - 1) / 7);
        if (dayCount == 5) {
            dayCount = -1;
        }
        bydayNum[0] = dayCount;
        byday[0] = EventRecurrence.timeDay2Day(startTime.weekDay);
        eventRecurrence.byday = byday;
        eventRecurrence.bydayNum = bydayNum;
    } else if (selection == REPEATS_YEARLY) {
        eventRecurrence.freq = EventRecurrence.YEARLY;
    }
    // Set the week start day.
    eventRecurrence.wkst = EventRecurrence.calendarDay2Day(weekStart);
    model.mRrule = eventRecurrence.toString();
}
Also used : EventRecurrence(com.android.calendarcommon2.EventRecurrence) Time(android.text.format.Time)

Example 2 with EventRecurrence

use of com.android.calendarcommon2.EventRecurrence in project Etar-Calendar by Etar-Group.

the class EditEventHelper method updatePastEvents.

/**
     * Prepares an update to the original event so it stops where the new series
     * begins. When we update 'this and all following' events we need to change
     * the original event to end before a new series starts. This creates an
     * update to the old event's rrule to do that.
     *<p>
     * If the event's recurrence rule has a COUNT, we also need to reduce the count in the
     * RRULE for the exception event.
     *
     * @param ops The list of operations to add the update to
     * @param originalModel The original event that we're updating
     * @param endTimeMillis The time before which the event must end (i.e. the start time of the
     *        exception event instance).
     * @return A replacement exception recurrence rule.
     */
public String updatePastEvents(ArrayList<ContentProviderOperation> ops, CalendarEventModel originalModel, long endTimeMillis) {
    boolean origAllDay = originalModel.mAllDay;
    String origRrule = originalModel.mRrule;
    String newRrule = origRrule;
    EventRecurrence origRecurrence = new EventRecurrence();
    origRecurrence.parse(origRrule);
    // Get the start time of the first instance in the original recurrence.
    long startTimeMillis = originalModel.mStart;
    Time dtstart = new Time();
    dtstart.timezone = originalModel.mTimezone;
    dtstart.set(startTimeMillis);
    ContentValues updateValues = new ContentValues();
    if (origRecurrence.count > 0) {
        /*
             * Generate the full set of instances for this recurrence, from the first to the
             * one just before endTimeMillis.  The list should never be empty, because this method
             * should not be called for the first instance.  All we're really interested in is
             * the *number* of instances found.
             *
             * TODO: the model assumes RRULE and ignores RDATE, EXRULE, and EXDATE.  For the
             * current environment this is reasonable, but that may not hold in the future.
             *
             * TODO: if COUNT is 1, should we convert the event to non-recurring?  e.g. we
             * do an "edit this and all future events" on the 2nd instances.
             */
        RecurrenceSet recurSet = new RecurrenceSet(originalModel.mRrule, null, null, null);
        RecurrenceProcessor recurProc = new RecurrenceProcessor();
        long[] recurrences;
        try {
            recurrences = recurProc.expand(dtstart, recurSet, startTimeMillis, endTimeMillis);
        } catch (DateException de) {
            throw new RuntimeException(de);
        }
        if (recurrences.length == 0) {
            throw new RuntimeException("can't use this method on first instance");
        }
        EventRecurrence excepRecurrence = new EventRecurrence();
        // TODO: add+use a copy constructor instead
        excepRecurrence.parse(origRrule);
        excepRecurrence.count -= recurrences.length;
        newRrule = excepRecurrence.toString();
        origRecurrence.count = recurrences.length;
    } else {
        // The "until" time must be in UTC time in order for Google calendar
        // to display it properly. For all-day events, the "until" time string
        // must include just the date field, and not the time field. The
        // repeating events repeat up to and including the "until" time.
        Time untilTime = new Time();
        untilTime.timezone = Time.TIMEZONE_UTC;
        // Subtract one second from the old begin time to get the new
        // "until" time.
        // subtract one second (1000 millis)
        untilTime.set(endTimeMillis - 1000);
        if (origAllDay) {
            untilTime.hour = 0;
            untilTime.minute = 0;
            untilTime.second = 0;
            untilTime.allDay = true;
            untilTime.normalize(false);
            // This should no longer be necessary -- DTSTART should already be in the correct
            // format for an all-day event.
            dtstart.hour = 0;
            dtstart.minute = 0;
            dtstart.second = 0;
            dtstart.allDay = true;
            dtstart.timezone = Time.TIMEZONE_UTC;
        }
        origRecurrence.until = untilTime.format2445();
    }
    updateValues.put(Events.RRULE, origRecurrence.toString());
    updateValues.put(Events.DTSTART, dtstart.normalize(true));
    ContentProviderOperation.Builder b = ContentProviderOperation.newUpdate(Uri.parse(originalModel.mUri)).withValues(updateValues);
    ops.add(b.build());
    return newRrule;
}
Also used : ContentValues(android.content.ContentValues) ContentProviderOperation(android.content.ContentProviderOperation) Time(android.text.format.Time) RecurrenceSet(com.android.calendarcommon2.RecurrenceSet) EventRecurrence(com.android.calendarcommon2.EventRecurrence) DateException(com.android.calendarcommon2.DateException) RecurrenceProcessor(com.android.calendarcommon2.RecurrenceProcessor)

Example 3 with EventRecurrence

use of com.android.calendarcommon2.EventRecurrence in project Etar-Calendar by Etar-Group.

the class EventInfoFragment method updateEvent.

private void updateEvent(View view) {
    if (mEventCursor == null || view == null) {
        return;
    }
    Context context = view.getContext();
    if (context == null) {
        return;
    }
    String eventName = mEventCursor.getString(EVENT_INDEX_TITLE);
    if (eventName == null || eventName.length() == 0) {
        eventName = getActivity().getString(R.string.no_title_label);
    }
    // Events.CONTENT_URI intent.  Update these with values read from the db.
    if (mStartMillis == 0 && mEndMillis == 0) {
        mStartMillis = mEventCursor.getLong(EVENT_INDEX_DTSTART);
        mEndMillis = mEventCursor.getLong(EVENT_INDEX_DTEND);
        if (mEndMillis == 0) {
            String duration = mEventCursor.getString(EVENT_INDEX_DURATION);
            if (!TextUtils.isEmpty(duration)) {
                try {
                    Duration d = new Duration();
                    d.parse(duration);
                    long endMillis = mStartMillis + d.getMillis();
                    if (endMillis >= mStartMillis) {
                        mEndMillis = endMillis;
                    } else {
                        Log.d(TAG, "Invalid duration string: " + duration);
                    }
                } catch (DateException e) {
                    Log.d(TAG, "Error parsing duration string " + duration, e);
                }
            }
            if (mEndMillis == 0) {
                mEndMillis = mStartMillis;
            }
        }
    }
    mAllDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
    String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION);
    String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION);
    String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
    String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE);
    mHeadlines.setBackgroundColor(mCurrentColor);
    // What
    if (eventName != null) {
        setTextCommon(view, R.id.title, eventName);
    }
    // When
    // Set the date and repeats (if any)
    String localTimezone = Utils.getTimeZone(mActivity, mTZUpdater);
    Resources resources = context.getResources();
    String displayedDatetime = Utils.getDisplayedDatetime(mStartMillis, mEndMillis, System.currentTimeMillis(), localTimezone, mAllDay, context);
    String displayedTimezone = null;
    if (!mAllDay) {
        displayedTimezone = Utils.getDisplayedTimezone(mStartMillis, localTimezone, eventTimezone);
    }
    // Display the datetime.  Make the timezone (if any) transparent.
    if (displayedTimezone == null) {
        setTextCommon(view, R.id.when_datetime, displayedDatetime);
    } else {
        int timezoneIndex = displayedDatetime.length();
        displayedDatetime += "  " + displayedTimezone;
        SpannableStringBuilder sb = new SpannableStringBuilder(displayedDatetime);
        ForegroundColorSpan transparentColorSpan = new ForegroundColorSpan(resources.getColor(R.color.event_info_headline_transparent_color));
        sb.setSpan(transparentColorSpan, timezoneIndex, displayedDatetime.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        setTextCommon(view, R.id.when_datetime, sb);
    }
    // Display the repeat string (if any)
    String repeatString = null;
    if (!TextUtils.isEmpty(rRule)) {
        EventRecurrence eventRecurrence = new EventRecurrence();
        eventRecurrence.parse(rRule);
        Time date = new Time(localTimezone);
        date.set(mStartMillis);
        if (mAllDay) {
            date.timezone = Time.TIMEZONE_UTC;
        }
        eventRecurrence.setStartDate(date);
        repeatString = EventRecurrenceFormatter.getRepeatString(mContext, resources, eventRecurrence, true);
    }
    if (repeatString == null) {
        view.findViewById(R.id.when_repeat).setVisibility(View.GONE);
    } else {
        setTextCommon(view, R.id.when_repeat, repeatString);
    }
    // Where
    if (location == null || location.trim().length() == 0) {
        setVisibilityCommon(view, R.id.where, View.GONE);
    } else {
        final TextView textView = mWhere;
        if (textView != null) {
            textView.setAutoLinkMask(0);
            textView.setText(location.trim());
            try {
                textView.setText(Utils.extendedLinkify(textView.getText().toString(), true));
                // Linkify.addLinks() sets the TextView movement method if it finds any links.
                // We must do the same here, in case linkify by itself did not find any.
                // (This is cloned from Linkify.addLinkMovementMethod().)
                MovementMethod mm = textView.getMovementMethod();
                if ((mm == null) || !(mm instanceof LinkMovementMethod)) {
                    if (textView.getLinksClickable()) {
                        textView.setMovementMethod(LinkMovementMethod.getInstance());
                    }
                }
            } catch (Exception ex) {
                // unexpected
                Log.e(TAG, "Linkification failed", ex);
            }
            textView.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    try {
                        return v.onTouchEvent(event);
                    } catch (ActivityNotFoundException e) {
                        // ignore
                        return true;
                    }
                }
            });
        }
    }
    // Description
    if (description != null && description.length() != 0) {
        mDesc.setText(description);
    }
    // Launch Custom App
    if (Utils.isJellybeanOrLater()) {
        updateCustomAppButton();
    }
}
Also used : Context(android.content.Context) OnTouchListener(android.view.View.OnTouchListener) ForegroundColorSpan(android.text.style.ForegroundColorSpan) LinkMovementMethod(android.text.method.LinkMovementMethod) Duration(com.android.calendarcommon2.Duration) Time(android.text.format.Time) ScrollView(android.widget.ScrollView) View(android.view.View) AdapterView(android.widget.AdapterView) AttendeesView(com.android.calendar.event.AttendeesView) TextView(android.widget.TextView) IOException(java.io.IOException) ActivityNotFoundException(android.content.ActivityNotFoundException) NameNotFoundException(android.content.pm.PackageManager.NameNotFoundException) DateException(com.android.calendarcommon2.DateException) MotionEvent(android.view.MotionEvent) EventRecurrence(com.android.calendarcommon2.EventRecurrence) ActivityNotFoundException(android.content.ActivityNotFoundException) LinkMovementMethod(android.text.method.LinkMovementMethod) MovementMethod(android.text.method.MovementMethod) DateException(com.android.calendarcommon2.DateException) TextView(android.widget.TextView) Resources(android.content.res.Resources) SpannableStringBuilder(android.text.SpannableStringBuilder)

Example 4 with EventRecurrence

use of com.android.calendarcommon2.EventRecurrence in project Etar-Calendar by Etar-Group.

the class DeleteEventHelper method deleteRepeatingEvent.

private void deleteRepeatingEvent(int which) {
    String rRule = mModel.mRrule;
    boolean allDay = mModel.mAllDay;
    long dtstart = mModel.mStart;
    // mCursor.getInt(mEventIndexId);
    long id = mModel.mId;
    switch(which) {
        case DELETE_SELECTED:
            {
                // the start time of the recurrence.
                if (dtstart == mStartMillis) {
                // TODO
                }
                // Create a recurrence exception by creating a new event
                // with the status "cancelled".
                ContentValues values = new ContentValues();
                // The title might not be necessary, but it makes it easier
                // to find this entry in the database when there is a problem.
                String title = mModel.mTitle;
                values.put(Events.TITLE, title);
                String timezone = mModel.mTimezone;
                long calendarId = mModel.mCalendarId;
                values.put(Events.EVENT_TIMEZONE, timezone);
                values.put(Events.ALL_DAY, allDay ? 1 : 0);
                values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0);
                values.put(Events.CALENDAR_ID, calendarId);
                values.put(Events.DTSTART, mStartMillis);
                values.put(Events.DTEND, mEndMillis);
                values.put(Events.ORIGINAL_SYNC_ID, mSyncId);
                values.put(Events.ORIGINAL_ID, id);
                values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis);
                values.put(Events.STATUS, Events.STATUS_CANCELED);
                mService.startInsert(mService.getNextToken(), null, Events.CONTENT_URI, values, Utils.UNDO_DELAY);
                break;
            }
        case DELETE_ALL:
            {
                Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
                mService.startDelete(mService.getNextToken(), null, uri, null, null, Utils.UNDO_DELAY);
                break;
            }
        case DELETE_ALL_FOLLOWING:
            {
                // following events, then delete them all.
                if (dtstart == mStartMillis) {
                    Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
                    mService.startDelete(mService.getNextToken(), null, uri, null, null, Utils.UNDO_DELAY);
                    break;
                }
                // Modify the repeating event to end just before this event time
                EventRecurrence eventRecurrence = new EventRecurrence();
                eventRecurrence.parse(rRule);
                Time date = new Time();
                if (allDay) {
                    date.timezone = Time.TIMEZONE_UTC;
                }
                date.set(mStartMillis);
                date.second--;
                date.normalize(false);
                // Google calendar seems to require the UNTIL string to be
                // in UTC.
                date.switchTimezone(Time.TIMEZONE_UTC);
                eventRecurrence.until = date.format2445();
                ContentValues values = new ContentValues();
                values.put(Events.DTSTART, dtstart);
                values.put(Events.RRULE, eventRecurrence.toString());
                Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, id);
                mService.startUpdate(mService.getNextToken(), null, uri, values, null, null, Utils.UNDO_DELAY);
                break;
            }
    }
    if (mCallback != null) {
        mCallback.run();
    }
    if (mExitWhenDone) {
        mParent.finish();
    }
}
Also used : ContentValues(android.content.ContentValues) EventRecurrence(com.android.calendarcommon2.EventRecurrence) Time(android.text.format.Time) Uri(android.net.Uri)

Aggregations

Time (android.text.format.Time)4 EventRecurrence (com.android.calendarcommon2.EventRecurrence)4 ContentValues (android.content.ContentValues)2 DateException (com.android.calendarcommon2.DateException)2 ActivityNotFoundException (android.content.ActivityNotFoundException)1 ContentProviderOperation (android.content.ContentProviderOperation)1 Context (android.content.Context)1 NameNotFoundException (android.content.pm.PackageManager.NameNotFoundException)1 Resources (android.content.res.Resources)1 Uri (android.net.Uri)1 SpannableStringBuilder (android.text.SpannableStringBuilder)1 LinkMovementMethod (android.text.method.LinkMovementMethod)1 MovementMethod (android.text.method.MovementMethod)1 ForegroundColorSpan (android.text.style.ForegroundColorSpan)1 MotionEvent (android.view.MotionEvent)1 View (android.view.View)1 OnTouchListener (android.view.View.OnTouchListener)1 AdapterView (android.widget.AdapterView)1 ScrollView (android.widget.ScrollView)1 TextView (android.widget.TextView)1