package com.openerp.support.calendar; import java.util.ArrayList; import java.util.List; import java.util.TimeZone; import android.accounts.Account; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; import android.provider.CalendarContract; import android.provider.CalendarContract.Calendars; import android.provider.CalendarContract.Events; import android.util.Log; import com.openerp.addons.meeting.MeetingDB; import com.openerp.auth.OpenERPAccountManager; import com.openerp.orm.OEDataRow; import com.openerp.orm.OEHelper; import com.openerp.orm.OEM2MIds; import com.openerp.orm.OEM2MIds.Operation; import com.openerp.orm.OEValues; import com.openerp.support.OEUser; import com.openerp.util.OEDate; public class OECalendar { public static final String TAG = "com.openerp.support.calendar.OECalendar"; Context mContext = null; ContentResolver mContentResolver = null; Account mAccount = null; Long mCalendarId = 0L; MeetingDB mMeetingDB = null; /** * Event Projections */ String[] mEventsProjection = new String[] { CalendarContract.Events._ID, CalendarContract.Events.TITLE, CalendarContract.Events.DESCRIPTION, CalendarContract.Events.CALENDAR_ID, CalendarContract.Events.DURATION, CalendarContract.Events.DTSTART, CalendarContract.Events.DTEND, CalendarContract.Events.EVENT_LOCATION, CalendarContract.Events.ALL_DAY }; public OECalendar(Context context) { Log.d(TAG, "OECalendar->constructor()"); mContext = context; mMeetingDB = new MeetingDB(mContext); mAccount = OpenERPAccountManager.getAccount(mContext, OEUser.current(mContext).getAndroidName()); mContentResolver = mContext.getContentResolver(); if (mAccount != null) initCalendar(); } private void initCalendar() { Log.d(TAG, "OECalendar->initCalendar()"); Uri mCalendarUri = Calendars.CONTENT_URI; long calendar_id = 0L; String[] projection = new String[] { Calendars._ID, Calendars.ACCOUNT_NAME, Calendars.CALENDAR_DISPLAY_NAME }; String selection = Calendars.ACCOUNT_NAME + " = ? "; String[] selectionArgs = new String[] { mAccount.name }; Cursor cr = mContentResolver.query(mCalendarUri, projection, selection, selectionArgs, null); if (cr.moveToFirst()) { calendar_id = cr.getLong(cr.getColumnIndex(Calendars._ID)); } else { calendar_id = createCalendar(); } cr.close(); mCalendarId = calendar_id; cr.close(); } private long createCalendar() { Log.d(TAG, "OECalendar->createCalendar()"); long calendar_id = 0; ContentValues values = new ContentValues(); values.put(Calendars.ACCOUNT_NAME, mAccount.name); values.put(CalendarContract.Calendars.ACCOUNT_TYPE, mAccount.type); values.put(Calendars.NAME, mAccount.name); values.put(Calendars.CALENDAR_DISPLAY_NAME, mAccount.name); values.put(Calendars.CALENDAR_COLOR, Color.parseColor("#cc0000")); values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER); values.put(Calendars.OWNER_ACCOUNT, mAccount.name); values.put(Calendars.SYNC_EVENTS, 1); values.put(Calendars.VISIBLE, 1); values.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, TimeZone .getDefault().getID()); Uri newUri = mContentResolver.insert(getSyncAdapter(), values); calendar_id = Long.parseLong(newUri.getLastPathSegment()); Log.d(TAG, "CreateCalendar()->calendar_id = " + calendar_id); return calendar_id; } private Uri getSyncAdapter() { Uri uri = Calendars.CONTENT_URI; return uri .buildUpon() .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true") .appendQueryParameter(Calendars.ACCOUNT_NAME, mAccount.name) .appendQueryParameter(Calendars.ACCOUNT_TYPE, mAccount.type) .build(); } public void syncCalendar() { Log.d(TAG, "OECalendar->syncCalendar()"); Log.i(TAG, "Calendar ID : " + mCalendarId); if (addNewMeetings()) { List<OEValues> calendarEvents = calendarEvents(); List<Integer> eventIds = new ArrayList<Integer>(); for (OEValues event : calendarEvents) eventIds.add(event.getInt(CalendarContract.Events._ID)); for (OEDataRow meeting : mMeetingDB.select()) { int event_id = meeting.getInt("calendar_event_id"); if (eventIds.contains(event_id)) { eventIds.remove(eventIds.indexOf(event_id)); } } if (pushOnServer(eventIds)) { updateAllEvents(); } } } private void updateAllEvents() { for (OEDataRow meeting : mMeetingDB.select()) { updateEvent(meeting); } } private boolean pushOnServer(List<Integer> eventIds) { if (eventIds.size() > 0) { OEHelper oe = mMeetingDB.getOEInstance(); if (oe != null) { for (int event_id : eventIds) { OEValues values = new OEValues(); OEValues event = selectEvent(event_id); values.put("name", event.getString(CalendarContract.Events.TITLE)); long startDate = event .getLong(CalendarContract.Events.DTSTART); long endDate = event.getLong(CalendarContract.Events.DTEND); values.put("date", OEDate.getDateFromMilis(startDate)); values.put("date_deadline", OEDate.getDateFromMilis(endDate)); int allday = event.getInt(CalendarContract.Events.ALL_DAY); values.put("duration", (allday == 1) ? allday : getDuration(startDate, endDate)); values.put("allday", (allday == 1) ? true : false); values.put("location", event .getString(CalendarContract.Events.EVENT_LOCATION)); values.put("description", event .getString(CalendarContract.Events.DESCRIPTION)); List<Integer> partners = new ArrayList<Integer>(); partners.add(OEUser.current(mContext).getPartner_id()); OEM2MIds partner_ids = new OEM2MIds(Operation.ADD, partners); values.put("partner_ids", partner_ids); int newId = oe.create(values); values = new OEValues(); values.put("calendar_event_id", event_id); values.put("calendar_id", mCalendarId); mMeetingDB.update(values, newId); } } } return true; } private float getDuration(long startDate, long endDate) { long offset = endDate - startDate; long datehours = offset / (60 * 60 * 1000); long dateminutes = offset / (60 * 1000); long duration = dateminutes - (datehours * 60); String hour = String.valueOf(datehours); String minute = String.valueOf(duration); StringBuffer durationString = new StringBuffer(); durationString.append(hour); durationString.append("."); durationString.append(minute); return Float.parseFloat(durationString.toString()); } private boolean addNewMeetings() { Log.d(TAG, "OECalendar->addNewMeetings()"); List<OEDataRow> new_meetings = mMeetingDB.select( "calendar_id IS NULL AND calendar_event_id IS NULL", new String[] {}); for (OEDataRow meeting : new_meetings) { long new_calendar_event_id = createEvent(meeting); OEValues values = new OEValues(); values.put("calendar_event_id", new_calendar_event_id); values.put("calendar_id", mCalendarId); int count = mMeetingDB.update(values, meeting.getInt("id")); Log.i(TAG, count + " meeting updated"); } return true; } public boolean removeEvents(List<OEDataRow> meetings) { Log.d(TAG, "OECalendar->removeMeetings()"); for (OEDataRow row : meetings) removeEvent(row.getInt("calendar_event_id")); return true; } private OEValues selectEvent(int event_id) { OEValues event = new OEValues(); Cursor cr = mContentResolver.query(Events.CONTENT_URI, mEventsProjection, CalendarContract.Events._ID + " = ?", new String[] { event_id + "" }, null); if (cr.moveToFirst()) { for (String key : mEventsProjection) { int index = cr.getColumnIndex(key); Object value = ""; if (cr.getString(index) != null) value = cr.getString(index); event.put(key, value); } } cr.close(); return event; } private List<OEValues> calendarEvents() { Log.d(TAG, "OECalendar->calendarEvents()"); List<OEValues> events = new ArrayList<OEValues>(); Cursor cr = mContentResolver.query(Events.CONTENT_URI, mEventsProjection, null, null, null); if (cr.moveToFirst()) { do { OEValues event = new OEValues(); for (String key : mEventsProjection) { int index = cr.getColumnIndex(key); if (cr.getType(index) == Cursor.FIELD_TYPE_INTEGER) event.put(key, cr.getInt(index)); else event.put(key, cr.getString(index)); } events.add(event); } while (cr.moveToNext()); } cr.close(); return events; } private boolean removeEvent(int event_id) { Log.d(TAG, "OECalendar->removeEvent()"); boolean flag = false; int count = mContentResolver.delete(Events.CONTENT_URI, CalendarContract.Events._ID + " = ? AND " + CalendarContract.Events.CALENDAR_ID + " = ?", new String[] { event_id + "", mCalendarId + "" }); if (count > 0) { flag = true; Log.i(TAG, "removedEvent : " + event_id); } return flag; } private long createEvent(OEDataRow meeting) { Log.d(TAG, "OECalendar->createEvent()"); long calendar_event_id = 0L; calendar_event_id = Long.parseLong(mContentResolver.insert( Events.CONTENT_URI, getValues(meeting)).getLastPathSegment()); Log.i(TAG, "OECalendar->createEvent() : " + calendar_event_id); return calendar_event_id; } private void updateEvent(OEDataRow meeting) { Log.d(TAG, "OECalendar->updateEvent()"); mContentResolver.update(Events.CONTENT_URI, getValues(meeting), Events._ID + " = ?", new String[] { meeting.getString("calendar_event_id") }); Log.i(TAG, "OECalendar->updateEvent() : " + meeting.getString("calendar_event_id")); } private ContentValues getValues(OEDataRow meeting) { ContentValues values = new ContentValues(); values.put(CalendarContract.Events.TITLE, meeting.getString("name")); String description = meeting.getString("description"); values.put(CalendarContract.Events.DESCRIPTION, (description.equals("false")) ? "" : description); values.put(CalendarContract.Events.CALENDAR_ID, mCalendarId); values.put(CalendarContract.Events.DTSTART, OEDate.getDateTimeInMilis(meeting.getString("date"))); values.put(CalendarContract.Events.ALL_DAY, meeting.getBoolean("allday")); values.put(CalendarContract.Events.DTEND, OEDate.getDateTimeInMilis(meeting.getString("date_deadline"))); String location = meeting.getString("location"); values.put(CalendarContract.Events.EVENT_LOCATION, (location.equals("false")) ? "" : location); values.put(CalendarContract.Events.EVENT_TIMEZONE, OEUser.current(mContext).getTimezone()); return values; } }