summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSara Ting <sarating@google.com>2012-08-14 12:47:17 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-08-14 12:47:18 -0700
commit4ddc6b9ff31660bf3d1377c6f527609fd8f1947e (patch)
treedb32d652bf12b2b5d5ca6294473f122c99cfb6f7 /src
parent487d52c2789114e0ee3e7ce85694611b8d59dd70 (diff)
parent601ef6e0e7b921141cfeaf849238e444a10b9687 (diff)
downloadandroid_packages_apps_Calendar-4ddc6b9ff31660bf3d1377c6f527609fd8f1947e.tar.gz
android_packages_apps_Calendar-4ddc6b9ff31660bf3d1377c6f527609fd8f1947e.tar.bz2
android_packages_apps_Calendar-4ddc6b9ff31660bf3d1377c6f527609fd8f1947e.zip
Merge "Add autocompletion for title in edit-event." into ics-ub-calendar-burgundy
Diffstat (limited to 'src')
-rw-r--r--src/com/android/calendar/event/EditEventView.java134
1 files changed, 132 insertions, 2 deletions
diff --git a/src/com/android/calendar/event/EditEventView.java b/src/com/android/calendar/event/EditEventView.java
index 57d56b14..1fbc8d5e 100644
--- a/src/com/android/calendar/event/EditEventView.java
+++ b/src/com/android/calendar/event/EditEventView.java
@@ -24,12 +24,14 @@ import android.app.ProgressDialog;
import android.app.Service;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.graphics.drawable.Drawable;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
@@ -43,14 +45,17 @@ import android.text.format.DateUtils;
import android.text.format.Time;
import android.text.util.Rfc822Tokenizer;
import android.util.Log;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.CheckBox;
@@ -64,6 +69,7 @@ import android.widget.ResourceCursorAdapter;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
import android.widget.TimePicker;
import com.android.calendar.CalendarEventModel;
@@ -93,6 +99,7 @@ import java.util.Formatter;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
+import java.util.TreeMap;
public class EditEventView implements View.OnClickListener, DialogInterface.OnCancelListener,
DialogInterface.OnClickListener, OnItemSelectedListener {
@@ -100,6 +107,16 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
private static final String GOOGLE_SECONDARY_CALENDAR = "calendar.google.com";
private static final String PERIOD_SPACE = ". ";
+ // Constants used for title autocompletion.
+ private static final String[] EVENT_PROJECTION = new String[] {
+ Events._ID,
+ Events.TITLE,
+ };
+ private static final int EVENT_INDEX_ID = 0;
+ private static final int EVENT_INDEX_TITLE = 1;
+ private static final String TITLE_WHERE = Events.TITLE + " LIKE ?";
+ private static final int MAX_TITLE_SUGGESTIONS = 4;
+
ArrayList<View> mEditOnlyList = new ArrayList<View>();
ArrayList<View> mEditViewList = new ArrayList<View>();
ArrayList<View> mViewOnlyList = new ArrayList<View>();
@@ -121,7 +138,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
Spinner mAvailabilitySpinner;
Spinner mAccessLevelSpinner;
RadioGroup mResponseRadioGroup;
- TextView mTitleTextView;
+ AutoCompleteTextView mTitleTextView;
TextView mLocationTextView;
TextView mDescriptionTextView;
TextView mWhenView;
@@ -627,6 +644,106 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
}
/**
+ * Adapter for title auto completion.
+ */
+ private static class TitleAdapter extends ResourceCursorAdapter {
+ private final ContentResolver mContentResolver;
+
+ public TitleAdapter(Context context) {
+ super(context, android.R.layout.simple_dropdown_item_1line, null, 0);
+ mContentResolver = context.getContentResolver();
+ }
+
+ @Override
+ public int getCount() {
+ return Math.min(MAX_TITLE_SUGGESTIONS, super.getCount());
+ }
+
+ private static String getTitleAtCursor(Cursor cursor) {
+ return cursor.getString(EVENT_INDEX_TITLE);
+ }
+
+ @Override
+ public final String convertToString(Cursor cursor) {
+ return getTitleAtCursor(cursor);
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ TextView textView = (TextView) view;
+ textView.setText(getTitleAtCursor(cursor));
+ }
+
+ @Override
+ public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
+ String filter = constraint == null ? "" : constraint.toString() + "%";
+ if (filter.isEmpty()) {
+ return null;
+ }
+ long startTime = System.currentTimeMillis();
+
+ // Query all titles prefixed with the constraint. There is no way to insert
+ // 'DISTINCT' or 'GROUP BY' to get rid of dupes, so use post-processing to
+ // remove dupes. We will order query results by descending event ID to show
+ // results that were most recently inputted.
+ Cursor tempCursor = mContentResolver.query(Events.CONTENT_URI, EVENT_PROJECTION,
+ TITLE_WHERE, new String[] { filter }, Events._ID + " DESC");
+ if (tempCursor != null) {
+ try {
+ // Post process query results.
+ Cursor c = uniqueTitlesCursor(tempCursor);
+
+ // Log the processing duration.
+ long duration = System.currentTimeMillis() - startTime;
+ StringBuilder msg = new StringBuilder();
+ msg.append("Autocomplete of ");
+ msg.append(constraint);
+ msg.append(": title query match took ");
+ msg.append(duration);
+ msg.append("ms.");
+ Log.d(TAG, msg.toString());
+ return c;
+ } finally {
+ tempCursor.close();
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Post-process the query results to return the first MAX_TITLE_SUGGESTIONS
+ * unique titles in alphabetical order.
+ */
+ private Cursor uniqueTitlesCursor(Cursor cursor) {
+ TreeMap<String, String[]> titleToQueryResults =
+ new TreeMap<String, String[]>(String.CASE_INSENSITIVE_ORDER);
+ int numColumns = cursor.getColumnCount();
+ cursor.moveToPosition(-1);
+
+ // Remove dupes.
+ while ((titleToQueryResults.size() < MAX_TITLE_SUGGESTIONS) && cursor.moveToNext()) {
+ String title = getTitleAtCursor(cursor).trim();
+ String data[] = new String[numColumns];
+ if (!titleToQueryResults.containsKey(title)) {
+ for (int i = 0; i < numColumns; i++) {
+ data[i] = cursor.getString(i);
+ }
+ titleToQueryResults.put(title, data);
+ }
+ }
+
+ // Copy the sorted results to a new cursor.
+ MatrixCursor newCursor = new MatrixCursor(EVENT_PROJECTION);
+ for (String[] result : titleToQueryResults.values()) {
+ newCursor.addRow(result);
+ }
+ newCursor.moveToFirst();
+ return newCursor;
+ }
+ }
+
+ /**
* Does prep steps for saving a calendar event.
*
* This triggers a parse of the attendees list and checks if the event is
@@ -829,7 +946,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
// cache all the widgets
mCalendarsSpinner = (Spinner) view.findViewById(R.id.calendars_spinner);
- mTitleTextView = (TextView) view.findViewById(R.id.title);
+ mTitleTextView = (AutoCompleteTextView) view.findViewById(R.id.title);
mLocationTextView = (TextView) view.findViewById(R.id.location);
mDescriptionTextView = (TextView) view.findViewById(R.id.description);
mTimezoneLabel = (TextView) view.findViewById(R.id.timezone_label);
@@ -863,6 +980,19 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
mAttendeesList = (MultiAutoCompleteTextView) view.findViewById(R.id.attendees);
mTitleTextView.setTag(mTitleTextView.getBackground());
+ mTitleTextView.setAdapter(new TitleAdapter(activity));
+ mTitleTextView.setOnEditorActionListener(new OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ // Dismiss the suggestions dropdown. Return false so the other
+ // side effects still occur (soft keyboard going away, etc.).
+ mTitleTextView.dismissDropDown();
+ }
+ return false;
+ }
+ });
+
mLocationTextView.setTag(mLocationTextView.getBackground());
mDescriptionTextView.setTag(mDescriptionTextView.getBackground());
mRepeatsSpinner.setTag(mRepeatsSpinner.getBackground());