From 11e8e73c408feb7735e78112a9e0eb6d53897423 Mon Sep 17 00:00:00 2001 From: mebitek Date: Tue, 20 Dec 2022 11:00:12 +0100 Subject: [PATCH] add widget show tasks --- README.md | 2 +- .../widget/CalendarAppWidgetModel.java | 49 ++++++++++++++++--- .../widget/CalendarAppWidgetService.java | 33 ++++++++++++- 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 581edb894..b06cceaf4 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ this app would be just a dream. So thanks to them! - Uses Android calendar sync. Works with Google Calendar, Exchange, etc. - Material designed. - Support offline calendar. -- Agenda widget. +- Agenda and task widget. - Multilingual UI. ## How to use Etar diff --git a/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetModel.java b/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetModel.java index ed98583ab..fe6a40e46 100644 --- a/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetModel.java +++ b/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetModel.java @@ -28,6 +28,10 @@ import com.android.calendarcommon2.Time; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; @@ -59,7 +63,7 @@ public CalendarAppWidgetModel(Context context, String timeZone) { mContext = context; } - public void buildFromCursor(Cursor cursor, String timeZone) { + public void buildFromCursor(Cursor cursor, String timeZone, Boolean isTask) { final Time recycle = new Time(timeZone); final ArrayList> mBuckets = new ArrayList>(CalendarAppWidgetService.MAX_DAYS); @@ -80,13 +84,26 @@ public void buildFromCursor(Cursor cursor, String timeZone) { final boolean allDay = cursor.getInt(CalendarAppWidgetService.INDEX_ALL_DAY) != 0; long start = cursor.getLong(CalendarAppWidgetService.INDEX_BEGIN); long end = cursor.getLong(CalendarAppWidgetService.INDEX_END); + if (start == 0) { + Calendar instance = Calendar.getInstance(); + instance.setTimeInMillis(end); + instance.add(Calendar.MINUTE, -30); + start = instance.getTimeInMillis(); + } final String title = cursor.getString(CalendarAppWidgetService.INDEX_TITLE); final String location = cursor.getString(CalendarAppWidgetService.INDEX_EVENT_LOCATION); // we don't compute these ourselves because it seems to produce the // wrong endDay for all day events - final int startDay = cursor.getInt(CalendarAppWidgetService.INDEX_START_DAY); - final int endDay = cursor.getInt(CalendarAppWidgetService.INDEX_END_DAY); + final int startDay; + final int endDay; + if (isTask) { + startDay = Time.getJulianDay(start, new Time().getGmtOffset()); + endDay = Time.getJulianDay(end, new Time().getGmtOffset()); + } else { + startDay = cursor.getInt(CalendarAppWidgetService.INDEX_START_DAY); + endDay = cursor.getInt(CalendarAppWidgetService.INDEX_END_DAY); + } final int color = cursor.getInt(CalendarAppWidgetService.INDEX_COLOR); final int selfStatus = cursor .getInt(CalendarAppWidgetService.INDEX_SELF_ATTENDEE_STATUS); @@ -111,18 +128,34 @@ public void buildFromCursor(Cursor cursor, String timeZone) { int i = mEventInfos.size(); mEventInfos.add(populateEventInfo(eventId, allDay, start, end, startDay, endDay, title, location, color, selfStatus)); + } + } + + public void populateBuckets(String timeZone) { + final Time recycle = new Time(timeZone); + recycle.set(System.currentTimeMillis()); + Collections.sort(mEventInfos, Comparator.comparing(u -> new Date(u.start))); + + final ArrayList> mBuckets = + new ArrayList>(CalendarAppWidgetService.MAX_DAYS); + for (int i = 0; i < CalendarAppWidgetService.MAX_DAYS; i++) { + mBuckets.add(new LinkedList()); + } + int i = 0; + for (EventInfo mEventInfo : mEventInfos) { // populate the day buckets that this event falls into - int from = Math.max(startDay, mTodayJulianDay); - int to = Math.min(endDay, mMaxJulianDay); + int from = Math.max(Time.getJulianDay(mEventInfo.start, new Time().getGmtOffset()), mTodayJulianDay); + int to = Math.min(Time.getJulianDay(mEventInfo.end, new Time().getGmtOffset()), mMaxJulianDay); for (int day = from; day <= to; day++) { LinkedList bucket = mBuckets.get(day - mTodayJulianDay); RowInfo rowInfo = new RowInfo(RowInfo.TYPE_MEETING, i); - if (allDay) { + if (mEventInfo.allDay) { bucket.addFirst(rowInfo); } else { bucket.add(rowInfo); } } + i++; } int day = mTodayJulianDay; @@ -134,7 +167,9 @@ public void buildFromCursor(Cursor cursor, String timeZone) { final DayInfo dayInfo = populateDayInfo(day, recycle); // Add the day header final int dayIndex = mDayInfos.size(); - mDayInfos.add(dayInfo); + if (!mDayInfos.contains(dayInfo)) { + mDayInfos.add(dayInfo); + } mRowInfos.add(new RowInfo(RowInfo.TYPE_DAY, dayIndex)); } diff --git a/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetService.java b/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetService.java index d26d10f41..50b2b771d 100644 --- a/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetService.java +++ b/app/src/main/java/com/android/calendar/widget/CalendarAppWidgetService.java @@ -24,6 +24,7 @@ import android.content.CursorLoader; import android.content.Intent; import android.content.Loader; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.Cursor; import android.database.MatrixCursor; @@ -40,8 +41,11 @@ import android.widget.RemoteViews; import android.widget.RemoteViewsService; +import androidx.core.content.ContextCompat; import com.android.calendar.DynamicTheme; +import com.android.calendar.Event; import com.android.calendar.Utils; +import com.android.calendar.persistence.tasks.DmfsOpenTasksContract; import com.android.calendar.widget.CalendarAppWidgetModel.DayInfo; import com.android.calendar.widget.CalendarAppWidgetModel.EventInfo; import com.android.calendar.widget.CalendarAppWidgetModel.RowInfo; @@ -70,6 +74,19 @@ public class CalendarAppWidgetService extends RemoteViewsService { Instances.DISPLAY_COLOR, Instances.SELF_ATTENDEE_STATUS, }; + + static final String[] TASK_PROJECTION = new String[]{ + DmfsOpenTasksContract.Tasks.COLUMN_IS_ALLDAY, + DmfsOpenTasksContract.Tasks.COLUMN_START_DATE, + DmfsOpenTasksContract.Tasks.COLUMN_DUE_DATE, + DmfsOpenTasksContract.Tasks.COLUMN_TITLE, + DmfsOpenTasksContract.Tasks.COLUMN_LOCATION, + DmfsOpenTasksContract.Tasks.COLUMN_ID, + DmfsOpenTasksContract.Tasks.COLUMN_START_DATE, + DmfsOpenTasksContract.Tasks.COLUMN_DUE_DATE, + DmfsOpenTasksContract.Tasks.COLUMN_LIST_COLOR, + "1 as selfAttendeeStatus", + }; static final int INDEX_ALL_DAY = 0; static final int INDEX_BEGIN = 1; static final int INDEX_END = 2; @@ -173,7 +190,7 @@ public CalendarFactory() { protected static CalendarAppWidgetModel buildAppWidgetModel( Context context, Cursor cursor, String timeZone) { CalendarAppWidgetModel model = new CalendarAppWidgetModel(context, timeZone); - model.buildFromCursor(cursor, timeZone); + model.buildFromCursor(cursor, timeZone, false); return model; } @@ -511,6 +528,20 @@ public void onLoadComplete(Loader loader, Cursor cursor) { MatrixCursor matrixCursor = Utils.matrixCursorFromCursor(cursor); try { mModel = buildAppWidgetModel(mContext, matrixCursor, tz); + long begin = now - DateUtils.DAY_IN_MILLIS; + long end = now + SEARCH_DURATION + DateUtils.DAY_IN_MILLIS; + + int mFirstLoadedJulianDay = Time.getJulianDay(begin, new Time().getGmtOffset()); + int mLastLoadedJulianDay = Time.getJulianDay(end, new Time().getGmtOffset()); + + if (ContextCompat.checkSelfPermission(mContext, DmfsOpenTasksContract.TASK_READ_PERMISSION) + == PackageManager.PERMISSION_GRANTED) { + Cursor cTasks = Event.instancesQueryForTasks(mContext.getContentResolver(), TASK_PROJECTION, mFirstLoadedJulianDay, mLastLoadedJulianDay); + MatrixCursor matrixCursorTasks = Utils.matrixCursorFromCursor(cTasks); + mModel.buildFromCursor(matrixCursorTasks, tz, true); + } + + mModel.populateBuckets(tz); } finally { if (matrixCursor != null) { matrixCursor.close();