Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Enabled adding of timestamped entries to calendar.

Multiple entries will be inserted for deadline, scheduled and/or
timestamp entries. Refactored CalendarSyncService.
  • Loading branch information...
commit 9da94b8e755b116689697cc5ff262227bc63fd4b 1 parent b6f7bb4
@hdweiss hdweiss authored
View
110 src/com/matburt/mobileorg/Parsing/NodePayload.java
@@ -1,9 +1,16 @@
package com.matburt.mobileorg.Parsing;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.Log;
public class NodePayload {
private StringBuilder payload = new StringBuilder();
@@ -14,10 +21,8 @@
private String content = null;
private String scheduled = null;
-
private String deadline = null;
- @SuppressWarnings("unused")
- private String timestamp = null;
+ private ArrayList<String> timestamps = new ArrayList<String>();
private String id = null; // Can be :ID: (or :ORIGINAL_ID: for agendas.org)
@@ -35,7 +40,7 @@ public void setContent(String content) {
public String getContent() {
if(this.content == null)
- this.content = cleanPayload();
+ cleanPayload();
return this.content;
}
@@ -61,15 +66,22 @@ public String getId() {
return this.id;
}
- private String cleanPayload() {
+ private void cleanPayload() {
this.scheduled = stripDate("SCHEDULED:");
this.deadline = stripDate("DEADLINE:");
- this.timestamp = stripDate("");
+ stripTimestamps();
stripTags();
stripFileProperties();
- return payload.toString().trim();
+ this.content = payload.toString().trim();
+ }
+
+ private void stripTimestamps() {
+ String date = "";
+ while((date = stripDate("")).equals("") == false) {
+ this.timestamps.add(date);
+ }
}
private String stripDate(String scheduled) {
@@ -109,7 +121,6 @@ private void stripTags() {
} else
end = payload.indexOf("\n", propm.end());
-
if(end == -1)
end = propm.end();
else {
@@ -140,19 +151,92 @@ private void stripFileProperties() {
}
}
+
/**
* Returns a string containing the time at which a todo is scheduled or deadlined.
*/
- public String getDate() {
- if(this.scheduled == null)
+ public ArrayList<DateEntry> getDates() {
+ ArrayList<DateEntry> result = new ArrayList<DateEntry>();
+
+ if(this.scheduled == null) {
this.scheduled = stripDate("SCHEDULED:");
+ DateEntry scheduledEntry = getDateEntry(this.scheduled);
+ if(scheduledEntry != null)
+ result.add(scheduledEntry);
+ }
- if(TextUtils.isEmpty(this.scheduled) && this.deadline == null) {
+ if(this.deadline == null) {
this.deadline = stripDate("DEADLINE:");
- return this.deadline;
+ DateEntry deadlineEntry = getDateEntry(this.deadline);
+ if(deadlineEntry != null)
+ result.add(deadlineEntry);
}
- return this.scheduled;
+ stripTimestamps();
+ for(String timestamp: this.timestamps) {
+ DateEntry timestampEntry = getDateEntry(timestamp);
+ if(timestampEntry != null)
+ result.add(timestampEntry);
+ }
+
+ return result;
+ }
+
+ public class DateEntry {
+ public long beginTime;
+ public long endTime;
+ public int allDay;
+ }
+
+ private DateEntry getDateEntry(String date)
+ throws IllegalArgumentException {
+ final Pattern schedulePattern = Pattern
+ .compile("(\\d{4}-\\d{2}-\\d{2})(?:[^\\d]*)(\\d{1,2}\\:\\d{2})?\\-?(\\d{1,2}\\:\\d{2})?");
+
+ Matcher propm = schedulePattern.matcher(date);
+ DateEntry result = new DateEntry();
+
+ if (propm.find()) {
+ try {
+ result.beginTime = getDateInMs(propm.group(1)).getTime();
+ result.beginTime += TimeZone.getDefault().getOffset(result.beginTime);
+
+ long beginTimeOfDay;
+ if (propm.group(2) != null) { // has hh:mm entry
+ beginTimeOfDay = getTimeInMs(propm.group(2)).getTime();
+ result.beginTime += beginTimeOfDay;
+ result.allDay = 0;
+
+ if (propm.group(3) != null) { // has hh:mm-hh:mm entry
+ result.endTime = result.beginTime
+ + getTimeInMs(propm.group(3)).getTime()
+ - beginTimeOfDay;
+ } else
+ // event is one hour per default
+ result.endTime = result.beginTime + DateUtils.HOUR_IN_MILLIS;
+ } else { // event is an entire day event
+ result.endTime = result.beginTime + DateUtils.DAY_IN_MILLIS;
+ result.allDay = 1;
+ }
+
+ return result;
+ } catch (ParseException e) {
+ Log.w("MobileOrg",
+ "Unable to parse schedule: " + date);
+ }
+ } else
+ Log.w("MobileOrg", "Unable to find time entry of entry");
+ return null;
+ }
+
+ private Date getDateInMs(String date) throws ParseException {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ return formatter.parse(date);
+ }
+
+ private Date getTimeInMs(String time) throws ParseException {
+ SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
+ return formatter.parse(time);
}
public String getScheduled() {
View
273 src/com/matburt/mobileorg/Services/CalendarSyncService.java
@@ -1,12 +1,6 @@
package com.matburt.mobileorg.Services;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.HashMap;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -20,11 +14,10 @@
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
-import android.text.format.DateUtils;
import android.text.format.Time;
-import android.util.Log;
import com.matburt.mobileorg.R;
+import com.matburt.mobileorg.Parsing.NodePayload.DateEntry;
import com.matburt.mobileorg.Parsing.NodeWrapper;
import com.matburt.mobileorg.Parsing.OrgDatabase;
@@ -47,26 +40,96 @@ public CalendarSyncService(OrgDatabase db, Context context) {
setupCalendar();
}
- private int getCalendarID(String calendarName) {
- Cursor cursor = context.getContentResolver().query(
- intCalendars.CONTENT_URI,
- new String[] { intCalendars._ID,
- intCalendars.CALENDAR_DISPLAY_NAME }, null,
- null, null);
- if (cursor != null && cursor.moveToFirst()) {
- for (int i = 0; i < cursor.getCount(); i++) {
- int calId = cursor.getInt(0);
- String calName = cursor.getString(1);
+ public void syncFiles() {
+ this.deleteAllEntries(context);
+
+ HashMap<String,String> files = this.db.getFiles();
+ files.remove("agendas.org");
+ for(String filename: files.keySet())
+ insertFileEntries(filename);
+ }
+
+ public void syncFile(String filename) throws IllegalArgumentException {
+ deleteFileEntries(filename, context);
+ insertFileEntries(filename);
+ }
+
+ public int deleteAllEntries(Context context) {
+ return context.getContentResolver()
+ .delete(intEvents.CONTENT_URI, "description LIKE ?",
+ new String[] { CALENDAR_ORGANIZER + "%" });
+ }
- if (calName.equals(calendarName)) {
- cursor.close();
- return calId;
+ public int deleteFileEntries(String filename, Context context) {
+ return context.getContentResolver().delete(intEvents.CONTENT_URI,
+ "description LIKE ?",
+ new String[] { CALENDAR_ORGANIZER + ":" + filename + "%" });
+ }
+
+
+ public CharSequence[] getCalendars(Context context) {
+ CharSequence[] result;
+
+ try {
+ Cursor cursor = context.getContentResolver().query(
+ intCalendars.CONTENT_URI,
+ new String[] { intCalendars._ID,
+ intCalendars.CALENDAR_DISPLAY_NAME }, null, null,
+ null);
+
+ if (cursor.getCount() == 0) {
+ result = new CharSequence[1];
+ result[0] = context
+ .getString(R.string.error_setting_no_calendar);
+ return result;
+ }
+
+ result = new CharSequence[cursor.getCount()];
+
+ if (cursor != null && cursor.moveToFirst()) {
+ for (int i = 0; i < cursor.getCount(); i++) {
+ result[i] = cursor.getString(1);
+ cursor.moveToNext();
}
- cursor.moveToNext();
}
+ cursor.close();
+ } catch (SQLException e) {
+ result = new CharSequence[1];
+ result[0] = context.getString(R.string.error_setting_no_calendar);
+ }
+
+ return result;
+ }
+
+
+ public void insertNode(long node_id) {
+ NodeWrapper node = new NodeWrapper(this.db.getNode(node_id));
+ insertNode(node, node.getFileName(db));
+ }
+
+ private void insertFileEntries(String filename) throws IllegalArgumentException {
+ Cursor scheduled = db.getFileSchedule(filename);
+
+ if (scheduled == null)
+ return;
+ while (scheduled.isAfterLast() == false) {
+ NodeWrapper node = new NodeWrapper(scheduled);
+ insertNode(node, filename);
+ scheduled.moveToNext();
+ }
+
+ scheduled.close();
+ }
+
+ private void insertNode(NodeWrapper node, String filename)
+ throws IllegalArgumentException {
+ boolean isActive = db.isTodoActive(node.getTodo());
+
+ for (DateEntry date : node.getPayload(db).getDates()) {
+ insertEntry(node.getName(), isActive, node.getCleanedPayload(db),
+ node.getNodeId(db), date.beginTime, date.endTime,
+ date.allDay, filename);
}
- cursor.close();
- return -1;
}
// TODO Speed up using bulkInserts
@@ -112,7 +175,7 @@ private String insertEntry(String name, boolean isTodoActive, String payload, St
return nodeID;
}
-
+
private void addReminder(String eventID, long beginTime, long endTime) {
if(beginTime < System.currentTimeMillis())
return;
@@ -144,150 +207,39 @@ private void addReminder(String eventID, long beginTime, long endTime) {
eventValues.put(intEvents.HAS_ALARM, 1);
context.getContentResolver().update(
ContentUris.withAppendedId(intEvents.CONTENT_URI,
- Long.valueOf(eventID)), eventValues, null, null);
-
- }
-
- public int deleteEntry(String calendarID) {
- return context.getContentResolver().delete(
- ContentUris.withAppendedId(intEvents.CONTENT_URI,
- Long.valueOf(calendarID)), null, null);
+ Long.valueOf(eventID)), eventValues, null, null);
}
- public int deleteFileEntries(String filename, Context context) {
- return context.getContentResolver().delete(intEvents.CONTENT_URI,
- "description LIKE ?",
- new String[] { CALENDAR_ORGANIZER + ":" + filename + "%" });
- }
-
- public int deleteAllEntries(Context context) {
- return context.getContentResolver()
- .delete(intEvents.CONTENT_URI, "description LIKE ?",
- new String[] { CALENDAR_ORGANIZER + "%" });
- }
-
- private Date getDateInMs(String date) throws ParseException {
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
- return formatter.parse(date);
- }
-
- private Date getTimeInMs(String time) throws ParseException {
- SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
- return formatter.parse(time);
- }
-
- public void insertNode(long node_id) {
- NodeWrapper node = new NodeWrapper(this.db.getNode(node_id));
- insertNode(node, node.getFileName(db));
- }
-
- private void insertNode(NodeWrapper node, String filename) throws IllegalArgumentException {
- final Pattern schedulePattern = Pattern
- .compile("(\\d{4}-\\d{2}-\\d{2})(?:[^\\d]*)(\\d{1,2}\\:\\d{2})?\\-?(\\d{1,2}\\:\\d{2})?");
- Matcher propm = schedulePattern.matcher(node.getPayload(db).getDate());
-
- long beginTime;
- long endTime;
- int allDay;
+ private int getCalendarID(String calendarName) {
+ Cursor cursor = context.getContentResolver().query(
+ intCalendars.CONTENT_URI,
+ new String[] { intCalendars._ID,
+ intCalendars.CALENDAR_DISPLAY_NAME }, null,
+ null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ for (int i = 0; i < cursor.getCount(); i++) {
+ int calId = cursor.getInt(0);
+ String calName = cursor.getString(1);
- if (propm.find()) {
- try {
- beginTime = getDateInMs(propm.group(1)).getTime();
- beginTime += TimeZone.getDefault().getOffset(beginTime);
-
- long beginTimeOfDay;
- if (propm.group(2) != null) { // has hh:mm entry
- beginTimeOfDay = getTimeInMs(propm.group(2)).getTime();
- beginTime += beginTimeOfDay;
- allDay = 0;
-
- if (propm.group(3) != null) { // has hh:mm-hh:mm entry
- endTime = beginTime + getTimeInMs(propm.group(3)).getTime() - beginTimeOfDay;
- }
- else // event is one hour per default
- endTime = beginTime + DateUtils.HOUR_IN_MILLIS;
- } else { // event is an entire day event
- endTime = beginTime + DateUtils.DAY_IN_MILLIS;
- allDay = 1;
+ if (calName.equals(calendarName)) {
+ cursor.close();
+ return calId;
}
-
- boolean isActive = db.isTodoActive(node.getTodo());
-
- insertEntry(node.getName(), isActive, node.getCleanedPayload(db),
- node.getNodeId(db), beginTime, endTime, allDay,
- filename);
-
- } catch (ParseException e) {
- Log.w("MobileOrg", "Unable to parse schedule of: " + node.getName() + " " + node.getPayload(db).getDate());
+ cursor.moveToNext();
}
- } else
- Log.w("MobileOrg", "Unable to find time entry in schedule of: "
- + node.getName());
- }
-
- public void insertFileEntries(String filename) throws IllegalArgumentException {
- Cursor scheduled = db.getFileSchedule(filename);
-
- if (scheduled == null)
- return;
- while (scheduled.isAfterLast() == false) {
- NodeWrapper node = new NodeWrapper(scheduled);
-
- insertNode(node, filename);
- scheduled.moveToNext();
}
-
- scheduled.close();
+ cursor.close();
+ return -1;
}
- public CharSequence[] getCalendars(Context context) {
- CharSequence[] result;
-
- try {
- Cursor cursor = context.getContentResolver().query(
- intCalendars.CONTENT_URI,
- new String[] { intCalendars._ID,
- intCalendars.CALENDAR_DISPLAY_NAME }, null, null,
- null);
-
- if (cursor.getCount() == 0) {
- result = new CharSequence[1];
- result[0] = context
- .getString(R.string.error_setting_no_calendar);
- return result;
- }
-
- result = new CharSequence[cursor.getCount()];
-
- if (cursor != null && cursor.moveToFirst()) {
- for (int i = 0; i < cursor.getCount(); i++) {
- result[i] = cursor.getString(1);
- cursor.moveToNext();
- }
- }
- cursor.close();
- } catch (SQLException e) {
- result = new CharSequence[1];
- result[0] = context.getString(R.string.error_setting_no_calendar);
- }
-
- return result;
- }
-
- public void syncFile(String filename) throws IllegalArgumentException {
- deleteFileEntries(filename, context);
- insertFileEntries(filename);
- }
-
- public void syncFiles() {
- this.deleteAllEntries(context);
-
- HashMap<String,String> files = this.db.getFiles();
- files.remove("agendas.org");
- for(String filename: files.keySet())
- insertFileEntries(filename);
+ @SuppressWarnings("unused")
+ private int deleteEntry(String nodeCalendarID) {
+ return context.getContentResolver().delete(
+ ContentUris.withAppendedId(intEvents.CONTENT_URI,
+ Long.valueOf(nodeCalendarID)), null, null);
}
+/*** Compatibility with Android 4.0 *****/
private class intEvents {
public Uri CONTENT_URI;
@@ -371,6 +323,7 @@ private void setupCalendar() {
intCalendarAlerts.STATE = CalendarAlerts.STATE;
intCalendarAlerts.MINUTES = CalendarAlerts.MINUTES;
} catch (NoClassDefFoundError e) {
+ // The classes referenced above are not available on pre 4.0 phones.
setupBaseUris();
}
}
@@ -385,7 +338,7 @@ private void setupBaseUris() {
}
/**
- * Hack to get the proper uri.
+ * Hack to get the proper calendar uri for pre 4.0 phones.
*/
private String getCalendarUriBase() {
String calendarUriBase = null;
Please sign in to comment.
Something went wrong with that request. Please try again.