Search in sources :

Example 1 with DateException

use of com.android.calendarcommon2.DateException 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 2 with DateException

use of com.android.calendarcommon2.DateException 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 3 with DateException

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

the class GoogleCalendarUriIntentFilter method onCreate.

@Override
protected void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    Intent intent = getIntent();
    if (intent != null) {
        Uri uri = intent.getData();
        if (uri != null) {
            String[] eidParts = extractEidAndEmail(uri);
            if (eidParts == null) {
                Log.i(TAG, "Could not find event for uri: " + uri);
            } else {
                final String syncId = eidParts[0];
                final String ownerAccount = eidParts[1];
                if (debug)
                    Log.d(TAG, "eidParts=" + syncId + "/" + ownerAccount);
                final String selection = Events._SYNC_ID + " LIKE \"%" + syncId + "\" AND " + Calendars.OWNER_ACCOUNT + " LIKE \"" + ownerAccount + "\"";
                if (debug)
                    Log.d(TAG, "selection: " + selection);
                Cursor eventCursor = getContentResolver().query(Events.CONTENT_URI, EVENT_PROJECTION, selection, null, Calendars.CALENDAR_ACCESS_LEVEL + " desc");
                if (debug)
                    Log.d(TAG, "Found: " + eventCursor.getCount());
                if (eventCursor == null || eventCursor.getCount() == 0) {
                    Log.i(TAG, "NOTE: found no matches on event with id='" + syncId + "'");
                    return;
                }
                Log.i(TAG, "NOTE: found " + eventCursor.getCount() + " matches on event with id='" + syncId + "'");
                try {
                    // Get info from Cursor
                    while (eventCursor.moveToNext()) {
                        int eventId = eventCursor.getInt(EVENT_INDEX_ID);
                        long startMillis = eventCursor.getLong(EVENT_INDEX_START);
                        long endMillis = eventCursor.getLong(EVENT_INDEX_END);
                        if (debug)
                            Log.d(TAG, "_id: " + eventCursor.getLong(EVENT_INDEX_ID));
                        if (debug)
                            Log.d(TAG, "startMillis: " + startMillis);
                        if (debug)
                            Log.d(TAG, "endMillis:   " + endMillis);
                        if (endMillis == 0) {
                            String duration = eventCursor.getString(EVENT_INDEX_DURATION);
                            if (debug)
                                Log.d(TAG, "duration:    " + duration);
                            if (TextUtils.isEmpty(duration)) {
                                continue;
                            }
                            try {
                                Duration d = new Duration();
                                d.parse(duration);
                                endMillis = startMillis + d.getMillis();
                                if (debug)
                                    Log.d(TAG, "startMillis! " + startMillis);
                                if (debug)
                                    Log.d(TAG, "endMillis!   " + endMillis);
                                if (endMillis < startMillis) {
                                    continue;
                                }
                            } catch (DateException e) {
                                if (debug)
                                    Log.d(TAG, "duration:" + e.toString());
                                continue;
                            }
                        }
                        // Pick up attendee status action from uri clicked
                        int attendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
                        if ("RESPOND".equals(uri.getQueryParameter("action"))) {
                            try {
                                switch(Integer.parseInt(uri.getQueryParameter("rst"))) {
                                    case // Yes
                                    1:
                                        attendeeStatus = Attendees.ATTENDEE_STATUS_ACCEPTED;
                                        break;
                                    case // No
                                    2:
                                        attendeeStatus = Attendees.ATTENDEE_STATUS_DECLINED;
                                        break;
                                    case // Maybe
                                    3:
                                        attendeeStatus = Attendees.ATTENDEE_STATUS_TENTATIVE;
                                        break;
                                }
                            } catch (NumberFormatException e) {
                            // ignore this error as if the response code
                            // wasn't in the uri.
                            }
                        }
                        final Uri calendarUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
                        intent = new Intent(Intent.ACTION_VIEW, calendarUri);
                        intent.setClass(this, EventInfoActivity.class);
                        intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis);
                        intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis);
                        if (attendeeStatus == Attendees.ATTENDEE_STATUS_NONE) {
                            startActivity(intent);
                        } else {
                            updateSelfAttendeeStatus(eventId, ownerAccount, attendeeStatus, intent);
                        }
                        finish();
                        return;
                    }
                } finally {
                    eventCursor.close();
                }
            }
        }
        // Can't handle the intent. Pass it on to the next Activity.
        try {
            startNextMatchingActivity(intent);
        } catch (ActivityNotFoundException ex) {
        // no browser installed? Just drop it.
        }
    }
    finish();
}
Also used : ActivityNotFoundException(android.content.ActivityNotFoundException) DateException(com.android.calendarcommon2.DateException) Intent(android.content.Intent) Duration(com.android.calendarcommon2.Duration) Cursor(android.database.Cursor) Uri(android.net.Uri)

Aggregations

DateException (com.android.calendarcommon2.DateException)3 ActivityNotFoundException (android.content.ActivityNotFoundException)2 Time (android.text.format.Time)2 Duration (com.android.calendarcommon2.Duration)2 EventRecurrence (com.android.calendarcommon2.EventRecurrence)2 ContentProviderOperation (android.content.ContentProviderOperation)1 ContentValues (android.content.ContentValues)1 Context (android.content.Context)1 Intent (android.content.Intent)1 NameNotFoundException (android.content.pm.PackageManager.NameNotFoundException)1 Resources (android.content.res.Resources)1 Cursor (android.database.Cursor)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