diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 134c0ed1c..10eb75b51 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -23,15 +23,15 @@ android:label="@string/read_tasks_permission" android:description="@string/read_tasks_permission"/> - + - + - + - + @@ -39,11 +39,11 @@ - + - + - + @@ -68,13 +68,13 @@ - + - + @@ -90,15 +90,15 @@ - + - + - + @@ -116,14 +116,14 @@ - + - + - + - - - - + + + + diff --git a/astrid/res/values/keys.xml b/astrid/res/values/keys.xml index 7fe1d2d08..8e3d4719b 100644 --- a/astrid/res/values/keys.xml +++ b/astrid/res/values/keys.xml @@ -1,23 +1,23 @@ @@ -30,28 +30,31 @@ notif_qstart notif_qend - + notif_default_reminder - + notif_annoy notif_vibrate - + notification_ringtone - + notif_theme - + colorize - + font_size - + nagging - + deadline_time backup - - titleVisible + + default_calendar_id + 1 + + titleVisible true deadlineVisible true diff --git a/astrid/res/values/strings-legacy.xml b/astrid/res/values/strings-legacy.xml index 777eab53c..72c77ade0 100644 --- a/astrid/res/values/strings-legacy.xml +++ b/astrid/res/values/strings-legacy.xml @@ -59,17 +59,17 @@ 1 Tag %d Tags - + - + - MMM d + MMM d M/dd HH:mm - D\na\ny\ns + D\na\ny\ns H\no\nu\nr\ns - + 1 Day @@ -110,10 +110,10 @@ 1 Sec %d Sec - + %s Ago - + @@ -123,9 +123,9 @@ hidden New Task Could Not Find Requested Tag! - + - + H @@ -143,7 +143,7 @@ Spent: Poke Every - + Repeats Every @@ -151,15 +151,15 @@ Next Alarm: Tags: Notes: - + Created: - + Deleted - + Add New Task - + New Task Tags @@ -180,7 +180,7 @@ Start Timer Stop Timer Postpone - + Sort/Filters Hidden/Blocked Tasks @@ -190,7 +190,7 @@ Sort By Name Sort By Due Date Sort Reverse - + Select an Action: Times You\'ve Postponed: %d Postpone for how long? @@ -202,19 +202,19 @@ Astrid: Editing Task Astrid: Editing Astrid: New Task - + Basic Dates Alerts - + Summary Task Name How Important is it? Tags: Tag Name - + How Long Will it Take? Time Already Spent on Task Absolute Deadline @@ -227,7 +227,7 @@ Hide Until This Task is Done Notes Enter Task Notes - + Periodic Reminders Every Notify me... @@ -237,7 +237,7 @@ Alarm Clock Mode Fixed Reminders Add New Reminder - + Time (hours : minutes) Remind Me Every @@ -250,7 +250,7 @@ If you don\'t want to see the new task right after you complete the old one, you \n Don't Show Help Anymore - + Save Discard @@ -259,17 +259,17 @@ If you don\'t want to see the new task right after you complete the old one, you Click to Set Start Timer Stop Timer - + Save Task Saved: due in %s Task Saved: due %s ago Task Saved - + - + Astrid says... - + Astrid: Tag View: @@ -282,12 +282,12 @@ If you don\'t want to see the new task right after you complete the old one, you Shortcut created on your home screen! Tag: [untagged] - + Sort A-Z Sort by Size - - - + + + Synchronization Services Actions @@ -305,7 +305,7 @@ If you don\'t want to see the new task right after you complete the old one, you If set, auto-sync only happens when Wifi is active Sync Error! Sorry for the inconvenience! Error: -Astrid 2.7 now performs synchronization with RTM in the background. You will +Astrid 2.7 now performs synchronization with RTM in the background. You will be directed to the preferences page to configure how often you want this to occur (it is a minor drain on battery). @@ -324,23 +324,23 @@ occur (it is a minor drain on battery). Updated: %d Deleted: %d Merged: %d - + Reading Remote Data Reading List: %s Synchronizing Repeating Task Transmitting: %s Locally Deleted Tasks Receiving: %s - + Please Log In to RTM... Sorry, there was an error verifying your login. Please try again. \n\n -Error Message: +Error Message: - - - + + + Loading... Updating List... @@ -352,13 +352,13 @@ Error Message: Snooze... Go Away! Hours/minutes to snooze? - - Delete + + Delete Delete this task? Remove this tag from all tasks? - + Stop the timer? - + Some things you may not know about Astrid:\n \n @@ -369,10 +369,10 @@ Some things you may not know about Astrid:\n \n Thanks for using Astrid!\n - + -It looks like you are using an app that can kill processes (%s)! If you can, +It looks like you are using an app that can kill processes (%s)! If you can, add Astrid to the exclusion list so it doesn\'t get killed. Otherwise, Astrid might not let you know when your tasks are due.\n @@ -397,64 +397,64 @@ Skipped %d tasks.\n Select a File to Restore - + Astrid Tag Alert - Astrid will send you a reminder + Astrid will send you a reminder when you have uncompleted tasks with the following criteria: Tagged with: - - + + - + Absolute Deadline! Goal Deadline! Working on: You have $NUM tagged $TAG! - - + + - + Could not find this item: Could not save:s Cannot access folder: %s Cannot access your SD card! - + Notifications - + Quiet Hours Start Start time to silence notifications for periodic reminders - + Quiet Hours End End time to silence notifications - + Default Reminders For new tasks, default reminder in days (i.e. 7). Blank to disable - + Persistent Mode If checked, LED and notifications must be cleared one at a time - + Notification Ringtone Choose a ringtone for Astrid\'s alerts Notification Icons Choose Astrid\'s notification bar icon - + Vibrate on Alert If checked, Astrid will vibrate when sounding an alarm - + Appearance - + Colorize Task List Different colors for different priorities - + Task List Size Font size on the main listing page Other - + Nag Messages Show Astrid\'s comments when viewing reminders and postponing tasks? @@ -462,22 +462,27 @@ Skipped %d tasks.\n # of days from now to set new deadlines Automatic Backups - + Perform daily backups to sdcard. - + Last backup failed: %s - + Last backup failed, could not read SD card - + Latest backup was on %s - + + Calendar + Calendar to store the events. + Astrid default + + Displayed Fields Select the fields to show in task list - + Task Title Task description Dates @@ -501,14 +506,14 @@ Skipped %d tasks.\n Astrid is the highly-acclaimed open-source task list that is simple enough to not get in your way, powerful enough to help you get stuff done! Tags, reminders, RememberTheMilk sync, Locale plug-in & more! - + translator-credits Loading... - + Read Astrid tasks - + diff --git a/astrid/res/xml/preferences.xml b/astrid/res/xml/preferences.xml index 76179df25..cad90874b 100644 --- a/astrid/res/xml/preferences.xml +++ b/astrid/res/xml/preferences.xml @@ -1,117 +1,121 @@ - - + + - - - - - - + + + + + - - + + - + - - + - - + - - + - + - + - + - + - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/astrid/src-legacy/com/timsu/astrid/activities/EditPreferences.java b/astrid/src-legacy/com/timsu/astrid/activities/EditPreferences.java index 35ee23b8a..938d0c108 100644 --- a/astrid/src-legacy/com/timsu/astrid/activities/EditPreferences.java +++ b/astrid/src-legacy/com/timsu/astrid/activities/EditPreferences.java @@ -20,11 +20,13 @@ package com.timsu.astrid.activities; import android.os.Bundle; +import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import com.flurry.android.FlurryAgent; import com.timsu.astrid.R; +import com.timsu.astrid.utilities.Calendars; import com.timsu.astrid.utilities.Constants; import com.timsu.astrid.utilities.Preferences; @@ -45,6 +47,9 @@ public class EditPreferences extends PreferenceActivity { String backupSummary = Preferences.getBackupSummary(this); if(backupSummary != null && backupPreference != null) backupPreference.setSummary(backupSummary); + + ListPreference defaultCalendarPreference = (ListPreference) findPreference(getString(R.string.prefs_defaultCalendar)); + Calendars.initCalendarsPreference(this, defaultCalendarPreference); } @Override diff --git a/astrid/src-legacy/com/timsu/astrid/activities/TaskEdit.java b/astrid/src-legacy/com/timsu/astrid/activities/TaskEdit.java index 5703f7912..a196d6b4d 100644 --- a/astrid/src-legacy/com/timsu/astrid/activities/TaskEdit.java +++ b/astrid/src-legacy/com/timsu/astrid/activities/TaskEdit.java @@ -766,12 +766,13 @@ public class TaskEdit extends TaskModificationTabbedActivity { protected void onPause() { // create calendar event if(addToCalendar.isChecked() && model.getCalendarUri() == null) { + Uri uri = Uri.parse("content://calendar/events"); ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put("title", name.getText().toString()); - values.put("calendar_id", 1); + values.put("calendar_id", Preferences.getDefaultCalendarIDSafe(this)); values.put("description", notes.getText().toString()); values.put("hasAlarm", 0); values.put("transparency", 0); @@ -781,11 +782,13 @@ public class TaskEdit extends TaskModificationTabbedActivity { model.getDefiniteDueDate(), model.getEstimatedSeconds(), values); - Uri result = cr.insert(uri, values); - if(result != null) - model.setCalendarUri(result.toString()); - else - Log.e("astrid", "Error creating calendar event!"); + Uri result = null; + try{ + result = cr.insert(uri, values); + model.setCalendarUri(result.toString()); + } catch (IllegalArgumentException e) { + Log.e("astrid", "Error creating calendar event!", e); + } } if(shouldSaveState) diff --git a/astrid/src-legacy/com/timsu/astrid/utilities/Calendars.java b/astrid/src-legacy/com/timsu/astrid/utilities/Calendars.java new file mode 100644 index 000000000..3d0a24c16 --- /dev/null +++ b/astrid/src-legacy/com/timsu/astrid/utilities/Calendars.java @@ -0,0 +1,179 @@ +package com.timsu.astrid.utilities; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.res.Resources; +import android.database.Cursor; +import android.net.Uri; +import android.preference.ListPreference; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.timsu.astrid.R; + +public class Calendars { + + // Private SDK + private static final Uri CALENDAR_CONTENT_URI = Uri + .parse("content://calendar/calendars"); // Calendars.CONTENT_URI + + private static final String ID_COLUMN_NAME = "_id"; + private static final String DISPLAY_COLUMN_NAME = "displayName"; + private static final String ACCES_LEVEL_COLUMN_NAME = "access_level"; + + private static final String[] CALENDARS_PROJECTION = new String[] { + ID_COLUMN_NAME, // Calendars._ID, + DISPLAY_COLUMN_NAME // Calendars.DISPLAY_NAME + }; + + // Only show calendars that the user can modify. Access level 500 + // corresponds to Calendars.CONTRIBUTOR_ACCESS + private static final String CALENDARS_WHERE = ACCES_LEVEL_COLUMN_NAME + " >= 500"; + + private static final String CALENDARS_WHERE_ID = ACCES_LEVEL_COLUMN_NAME+" >= 500 AND" + ID_COLUMN_NAME +"=?"; + + private static final String CALENDARS_SORT = "displayName ASC"; + + /** + * Ensures that the default calendar preference is pointing to + * user-modifiable calendar that exists. If the calendar does not exist + * anymore, the preference is reset to default value. + * + * @param context + * Context + */ + public static void ensureValidDefaultCalendarPreference(Context context) { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(context); + Resources r = context.getResources(); + Editor editor = prefs.edit(); + // We default the 'defaultCalendar' setting when it is undefined + // or when the calendar does not exist anymore + if (!prefs.contains(r.getString(R.string.prefs_defaultCalendar)) + || !Calendars.isCalendarPresent(context, prefs.getString(r + .getString(R.string.prefs_defaultCalendar), null))) { + editor.putString(r.getString(R.string.prefs_defaultCalendar), r + .getString(R.string.prefs_defaultCalendar_default)); + editor.commit(); + } + } + + /** + * Appends all user-modifiable calendars to listPreference. Always includes + * entry called "Astrid default" with calendar id of + * prefs_defaultCalendar_default. + * + * @param context + * context + * @param listPreference + * preference to init + */ + public static void initCalendarsPreference(Context context, + ListPreference listPreference) { + + ContentResolver cr = context.getContentResolver(); + Resources r = context.getResources(); + Cursor c = cr.query(CALENDAR_CONTENT_URI, CALENDARS_PROJECTION, + CALENDARS_WHERE, null, CALENDARS_SORT); + + // Fetch the current setting. Invalid calendar id will + // be changed to default value. + String currentSetting = String.valueOf(Preferences + .getDefaultCalendarIDSafe(context)); + + int currentSettingIndex = -1; + + if (c == null) { + // Something went wrong when querying calendars + // Let's keep the "Astrid default" only. + listPreference + .setEntries(new String[] { r + .getString(R.string.prefs_defaultCalendar_astrid_default) }); + listPreference.setEntryValues(new String[] { r + .getString(R.string.prefs_defaultCalendar_default) }); + listPreference.setValueIndex(0); + listPreference.setEnabled(true); + return; + } + + int calendarCount = c.getCount(); + + String[] entries = new String[calendarCount]; + String[] entryValues = new String[calendarCount]; + + + // Iterate calendars one by one, and fill up the list preference + try { + int row = 0; + int idColumn = c.getColumnIndex(ID_COLUMN_NAME); + int nameColumn = c.getColumnIndex(DISPLAY_COLUMN_NAME); + while (c.moveToNext()) { + String id = c.getString(idColumn); + String name = c.getString(nameColumn); + entries[row] = name; + entryValues[row] = id; + + // We found currently selected calendar + if (currentSetting.equals(id)) { + currentSettingIndex = row; + } + + row++; + } + + if (currentSettingIndex == -1) { + // Should not happen! + // Let's keep the "Astrid default" only. + Log.d("astrid", "initCalendarsPreference: Unknown calendar."); + listPreference + .setEntries(new String[] { r + .getString(R.string.prefs_defaultCalendar_astrid_default) }); + listPreference.setEntryValues(new String[] { r + .getString(R.string.prefs_defaultCalendar_default) }); + listPreference.setValueIndex(0); + listPreference.setEnabled(true); + } + + listPreference.setEntries(entries); + listPreference.setEntryValues(entryValues); + + listPreference.setValueIndex(currentSettingIndex); + listPreference.setEnabled(true); + + } finally { + c.deactivate(); + } + } + + /** + * Checks whether user-modifiable calendar is present with a given id. + * + * @param context + * Context + * @param id + * Calendar ID to search for + * @return true, if user-modifiable calendar with the given id exists; false + * otherwise. + */ + private static boolean isCalendarPresent(Context context, String id) { + if (id == null) + return false; + + ContentResolver cr = context.getContentResolver(); + Cursor c = null; + + try { + c = cr.query(CALENDAR_CONTENT_URI, CALENDARS_PROJECTION, + CALENDARS_WHERE_ID, new String[] { id }, CALENDARS_SORT); + } finally { + if (c != null) { + c.deactivate(); + } + } + + return (c != null) && (c.getCount() != 0); + } + +} \ No newline at end of file diff --git a/astrid/src-legacy/com/timsu/astrid/utilities/Preferences.java b/astrid/src-legacy/com/timsu/astrid/utilities/Preferences.java index ed122c301..0a52c3261 100644 --- a/astrid/src-legacy/com/timsu/astrid/utilities/Preferences.java +++ b/astrid/src-legacy/com/timsu/astrid/utilities/Preferences.java @@ -68,6 +68,8 @@ public class Preferences { editor.putString(P_BACKUP_ERROR, null); } + Calendars.ensureValidDefaultCalendarPreference(context); + setVisibilityPreferences(prefs, editor, r); editor.commit(); @@ -110,7 +112,7 @@ public class Preferences { // --- system preferences - /** CurrentVersion: the currently installed version of Astrid */ + /** CurrentVersion: the currently installed version of Astrid */ public static int getCurrentVersion(Context context) { return getPrefs(context).getInt(P_CURRENT_VERSION, 0); } @@ -444,6 +446,28 @@ public class Preferences { editor.commit(); } + /** Get default calendar id. */ + public static String getDefaultCalendarID(Context context) { + Resources r = context.getResources(); + return getPrefs(context).getString( + r.getString(R.string.prefs_defaultCalendar), + r.getString(R.string.prefs_defaultCalendar_default)); + } + + /** Get default calendar id. Returns default value if the calendar does not exist anymore.*/ + public static String getDefaultCalendarIDSafe(Context context) { + Calendars.ensureValidDefaultCalendarPreference(context); + return getDefaultCalendarID(context); + } + + /** Set default calendar id */ + public static void setDefaultCalendarID(Context context, String value) { + Resources r = context.getResources(); + Editor editor = getPrefs(context).edit(); + editor.putString(r.getString(R.string.prefs_defaultCalendar), value); + editor.commit(); + } + // --- helper methods /** Clear the given preference */