mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
7.7 KiB
Java
215 lines
7.7 KiB
Java
/**
|
|
* Copyright (c) 2012 Todoroo Inc
|
|
*
|
|
* See the file "LICENSE" for the full license governing this code.
|
|
*/
|
|
package com.todoroo.astrid.gcal;
|
|
|
|
import android.content.ContentResolver;
|
|
import android.content.ContentValues;
|
|
import android.content.Context;
|
|
import android.net.Uri;
|
|
import android.provider.CalendarContract;
|
|
import android.text.TextUtils;
|
|
import android.text.format.Time;
|
|
|
|
import com.todoroo.andlib.utility.DateUtilities;
|
|
import com.todoroo.astrid.data.Task;
|
|
import com.todoroo.astrid.service.TaskService;
|
|
|
|
import org.tasks.R;
|
|
import org.tasks.calendars.AndroidCalendarEvent;
|
|
import org.tasks.calendars.CalendarEventProvider;
|
|
import org.tasks.injection.ForApplication;
|
|
import org.tasks.preferences.PermissionChecker;
|
|
import org.tasks.preferences.Preferences;
|
|
|
|
import java.util.TimeZone;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
import timber.log.Timber;
|
|
|
|
public class GCalHelper {
|
|
|
|
/** If task has no estimated time, how early to set a task in calendar (seconds)*/
|
|
private static final long DEFAULT_CAL_TIME = DateUtilities.ONE_HOUR;
|
|
|
|
private final TaskService taskService;
|
|
private final Preferences preferences;
|
|
private final PermissionChecker permissionChecker;
|
|
private final CalendarEventProvider calendarEventProvider;
|
|
private final ContentResolver cr;
|
|
|
|
@Inject
|
|
public GCalHelper(@ForApplication Context context, TaskService taskService, Preferences preferences,
|
|
PermissionChecker permissionChecker, CalendarEventProvider calendarEventProvider) {
|
|
this.taskService = taskService;
|
|
this.preferences = preferences;
|
|
this.permissionChecker = permissionChecker;
|
|
this.calendarEventProvider = calendarEventProvider;
|
|
cr = context.getContentResolver();
|
|
}
|
|
|
|
public String getTaskEventUri(Task task) {
|
|
String uri;
|
|
if (!TextUtils.isEmpty(task.getCalendarURI())) {
|
|
uri = task.getCalendarURI();
|
|
} else {
|
|
task = taskService.fetchById(task.getId(), Task.CALENDAR_URI);
|
|
if(task == null) {
|
|
return null;
|
|
}
|
|
uri = task.getCalendarURI();
|
|
}
|
|
|
|
return uri;
|
|
}
|
|
|
|
public void createTaskEventIfEnabled(Task t) {
|
|
if (!t.hasDueDate()) {
|
|
return;
|
|
}
|
|
createTaskEventIfEnabled(t, true);
|
|
}
|
|
|
|
private void createTaskEventIfEnabled(Task t, boolean deleteEventIfExists) {
|
|
if (preferences.isDefaultCalendarSet()) {
|
|
Uri calendarUri = createTaskEvent(t, new ContentValues(), deleteEventIfExists);
|
|
if (calendarUri != null) {
|
|
t.setCalendarUri(calendarUri.toString());
|
|
}
|
|
}
|
|
}
|
|
|
|
public Uri createTaskEvent(Task task, ContentValues values) {
|
|
return createTaskEvent(task, values, true);
|
|
}
|
|
|
|
public Uri createTaskEvent(Task task, ContentValues values, boolean deleteEventIfExists) {
|
|
if (!permissionChecker.canAccessCalendars()) {
|
|
return null;
|
|
}
|
|
|
|
String eventuri = getTaskEventUri(task);
|
|
|
|
if(!TextUtils.isEmpty(eventuri) && deleteEventIfExists) {
|
|
deleteTaskEvent(task);
|
|
}
|
|
|
|
try {
|
|
values.put(CalendarContract.Events.TITLE, task.getTitle());
|
|
values.put(CalendarContract.Events.DESCRIPTION, task.getNotes());
|
|
values.put(CalendarContract.Events.HAS_ALARM, 0);
|
|
boolean valuesContainCalendarId = (values.containsKey(CalendarContract.Events.CALENDAR_ID) &&
|
|
!TextUtils.isEmpty(values.getAsString(CalendarContract.Events.CALENDAR_ID)));
|
|
if (!valuesContainCalendarId) {
|
|
String calendarId = preferences.getDefaultCalendar();
|
|
if (!TextUtils.isEmpty(calendarId)) {
|
|
values.put(CalendarContract.Events.CALENDAR_ID, calendarId);
|
|
}
|
|
}
|
|
|
|
createStartAndEndDate(task, values);
|
|
|
|
//noinspection MissingPermission
|
|
Uri eventUri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
|
|
cr.notifyChange(eventUri, null);
|
|
|
|
return eventUri;
|
|
} catch (Exception e) {
|
|
// won't work on emulator
|
|
Timber.e(e, e.getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public void rescheduleRepeatingTask(Task task) {
|
|
String taskUri = getTaskEventUri(task);
|
|
if (TextUtils.isEmpty(taskUri)) {
|
|
return;
|
|
}
|
|
|
|
Uri eventUri = Uri.parse(taskUri);
|
|
|
|
AndroidCalendarEvent event = calendarEventProvider.getEvent(eventUri);
|
|
if (event == null) {
|
|
task.setCalendarUri("");
|
|
return;
|
|
}
|
|
ContentValues cv = new ContentValues();
|
|
cv.put(CalendarContract.Events.CALENDAR_ID, event.getCalendarId());
|
|
|
|
Uri uri = createTaskEvent(task, cv, false);
|
|
task.setCalendarUri(uri.toString());
|
|
}
|
|
|
|
public boolean deleteTaskEvent(Task task) {
|
|
boolean eventDeleted = false;
|
|
String uri;
|
|
if(task.containsNonNullValue(Task.CALENDAR_URI)) {
|
|
uri = task.getCalendarURI();
|
|
} else {
|
|
task = taskService.fetchById(task.getId(), Task.CALENDAR_URI);
|
|
if(task == null) {
|
|
return false;
|
|
}
|
|
uri = task.getCalendarURI();
|
|
}
|
|
|
|
if(!TextUtils.isEmpty(uri)) {
|
|
try {
|
|
Uri calendarUri = Uri.parse(uri);
|
|
if (calendarEventProvider.hasEvent(calendarUri)) {
|
|
cr.delete(calendarUri, null, null);
|
|
eventDeleted = true;
|
|
}
|
|
task.setCalendarUri("");
|
|
} catch (Exception e) {
|
|
Timber.e(e, e.getMessage());
|
|
}
|
|
}
|
|
|
|
return eventDeleted;
|
|
}
|
|
|
|
public void createStartAndEndDate(Task task, ContentValues values) {
|
|
long dueDate = task.getDueDate();
|
|
long tzCorrectedDueDate = dueDate + TimeZone.getDefault().getOffset(dueDate);
|
|
long tzCorrectedDueDateNow = DateUtilities.now() + TimeZone.getDefault().getOffset(DateUtilities.now());
|
|
// FIXME: doesnt respect timezones, see story 17443653
|
|
if(task.hasDueDate()) {
|
|
if(task.hasDueTime()) {
|
|
long estimatedTime = task.getEstimatedSeconds() * 1000;
|
|
if(estimatedTime <= 0) {
|
|
estimatedTime = DEFAULT_CAL_TIME;
|
|
}
|
|
if (preferences.getBoolean(R.string.p_end_at_deadline, true)) {
|
|
values.put(CalendarContract.Events.DTSTART, dueDate);
|
|
values.put(CalendarContract.Events.DTEND, dueDate + estimatedTime);
|
|
}else{
|
|
values.put(CalendarContract.Events.DTSTART, dueDate - estimatedTime);
|
|
values.put(CalendarContract.Events.DTEND, dueDate);
|
|
}
|
|
// setting a duetime to a previously timeless event requires explicitly setting allDay=0
|
|
values.put(CalendarContract.Events.ALL_DAY, "0");
|
|
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
|
|
} else {
|
|
values.put(CalendarContract.Events.DTSTART, tzCorrectedDueDate);
|
|
values.put(CalendarContract.Events.DTEND, tzCorrectedDueDate);
|
|
values.put(CalendarContract.Events.ALL_DAY, "1");
|
|
}
|
|
} else {
|
|
values.put(CalendarContract.Events.DTSTART, tzCorrectedDueDateNow);
|
|
values.put(CalendarContract.Events.DTEND, tzCorrectedDueDateNow);
|
|
values.put(CalendarContract.Events.ALL_DAY, "1");
|
|
}
|
|
if ("1".equals(values.get(CalendarContract.Events.ALL_DAY))) {
|
|
values.put(CalendarContract.Events.EVENT_TIMEZONE, Time.TIMEZONE_UTC);
|
|
} else {
|
|
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
|
|
}
|
|
}
|
|
}
|