summaryrefslogtreecommitdiffstats
path: root/src/com/android/calendar/IcsImportActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/calendar/IcsImportActivity.java')
-rw-r--r--src/com/android/calendar/IcsImportActivity.java227
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.
+ }
+}