diff options
Diffstat (limited to 'src/com/android/calendar/IcsImportActivity.java')
-rw-r--r-- | src/com/android/calendar/IcsImportActivity.java | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/src/com/android/calendar/IcsImportActivity.java b/src/com/android/calendar/IcsImportActivity.java new file mode 100644 index 00000000..c4f5fdea --- /dev/null +++ b/src/com/android/calendar/IcsImportActivity.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.calendar; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.pim.ICalendar; +import android.provider.Calendar; +import android.util.Config; +import android.util.Log; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + +public class IcsImportActivity extends Activity { + + private static final String TAG = "Calendar"; + + // TODO: consolidate this code with the EventActivity + private static class CalendarInfo { + public final long id; + public final String name; + + public CalendarInfo(long id, String name) { + this.id = id; + this.name = name; + } + + @Override + public String toString() { + return name; + } + } + + private View mView; + private Button mImportButton; + private Button mCancelButton; + private Spinner mCalendars; + private ImageView mCalendarIcon; + private TextView mNumEvents; + + private ICalendar.Component mCalendar = null; + + private View.OnClickListener mImportListener = new View.OnClickListener() { + public void onClick(View v) { + importCalendar(); + finish(); + } + }; + + private View.OnClickListener mCancelListener = new View.OnClickListener() { + public void onClick(View v) { + finish(); + } + }; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + setContentView(R.layout.ics_import_activity); + mView = findViewById(R.id.import_ics); + + mCalendarIcon = (ImageView) findViewById(R.id.calendar_icon); + mCalendars = (Spinner) findViewById(R.id.calendars); + populateCalendars(); + + mImportButton = (Button) findViewById(R.id.import_button); + mImportButton.setOnClickListener(mImportListener); + mCancelButton = (Button) findViewById(R.id.cancel_button); + mCancelButton.setOnClickListener(mCancelListener); + + mNumEvents = (TextView) findViewById(R.id.num_events); + + Intent intent = getIntent(); + String data = intent.getStringExtra("ics"); + if (data == null) { + Uri content = intent.getData(); + if (content != null) { + InputStream is = null; + try { + is = getContentResolver().openInputStream(content); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buf = new byte[8096]; + int bytesRead = -1; + int pos = 0; + while ((bytesRead = is.read(buf)) != -1) { + baos.write(buf, pos, bytesRead); + pos += bytesRead; + } + data = new String(baos.toByteArray(), "UTF-8"); + } catch (FileNotFoundException fnfe) { + Log.w(TAG, "Could not open data.", fnfe); + } catch (IOException ioe) { + Log.w(TAG, "Could not read data.", ioe); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException ioe) { + Log.w(TAG, "Could not close InputStream.", ioe); + } + } + } + } + } + if (data == null) { + Log.w(TAG, "No iCalendar data to parse."); + finish(); + return; + } + parseCalendar(data); + } + + private void populateCalendars() { + ContentResolver cr = getContentResolver(); + Cursor c = cr.query(Calendar.Calendars.CONTENT_URI, + new String[] { Calendar.Calendars._ID, + Calendar.Calendars.DISPLAY_NAME, + Calendar.Calendars.SELECTED, + Calendar.Calendars.ACCESS_LEVEL }, + Calendar.Calendars.SELECTED + "=1 AND " + + Calendar.Calendars.ACCESS_LEVEL + ">=" + + Calendar.Calendars.CONTRIBUTOR_ACCESS, + null, null /* sort order */); + + ArrayList<CalendarInfo> items = new ArrayList<CalendarInfo>(); + try { + // TODO: write a custom adapter that wraps the cursor? + int idColumn = c.getColumnIndex(Calendar.Calendars._ID); + int nameColumn = c.getColumnIndex(Calendar.Calendars.DISPLAY_NAME); + while (c.moveToNext()) { + long id = c.getLong(idColumn); + String name = c.getString(nameColumn); + items.add(new CalendarInfo(id, name)); + } + } finally { + c.deactivate(); + } + + mCalendars.setAdapter(new ArrayAdapter<CalendarInfo>(this, + android.R.layout.simple_spinner_item, items)); + } + + private void parseCalendar(String data) { + mCalendar = null; + try { + mCalendar = ICalendar.parseCalendar(data); + } catch (ICalendar.FormatException fe) { + if (Config.LOGD) { + Log.d(TAG, "Could not parse iCalendar.", fe); + // TODO: show an error message. + finish(); + return; + } + } + if (mCalendar.getComponents() == null) { + Log.d(TAG, "No events in iCalendar."); + finish(); + return; + } + int numEvents = 0; + for (ICalendar.Component component : mCalendar.getComponents()) { + if ("VEVENT".equals(component.getName())) { + // TODO: display a list of the events (start time, title) in + // the UI? + ++numEvents; + } + } + // TODO: special-case a single-event calendar. switch to the + // EventActivity, once the EventActivity supports displaying data that + // is passed in via the extras. + // OR, we could flip things around, where the EventActivity handles ICS + // import by default, and delegates to the IcsImportActivity if it finds + // that there are more than one event in the iCalendar. that would + // avoid an extra activity launch for the expected common case of + // importing a single event. + mNumEvents.setText(Integer.toString(numEvents)); + } + + private void importCalendar() { + + ContentResolver cr = getContentResolver(); + + int numImported = 0; + ContentValues values = new ContentValues(); + + for (ICalendar.Component component : mCalendar.getComponents()) { + if ("VEVENT".equals(component.getName())) { + CalendarInfo calInfo = + (CalendarInfo) mCalendars.getSelectedItem(); + if (Calendar.Events.insertVEvent(cr, component, calInfo.id, + Calendar.Events.STATUS_CONFIRMED, values) != null) { + ++numImported; + } + } + } + // TODO: display how many were imported. + } +} |