Merge change I53f94fc2 into eclair
* changes:
Tweaked the dialer screen to match the designer's PPL.
diff --git a/res/drawable-hdpi-finger/ic_join.png b/res/drawable-hdpi-finger/ic_join.png
new file mode 100644
index 0000000..8f140d4
--- /dev/null
+++ b/res/drawable-hdpi-finger/ic_join.png
Binary files differ
diff --git a/res/drawable-hdpi/bg_infobar_new.9.png b/res/drawable-hdpi/bg_infobar_new.9.png
new file mode 100644
index 0000000..104ced9
--- /dev/null
+++ b/res/drawable-hdpi/bg_infobar_new.9.png
Binary files differ
diff --git a/res/drawable-mdpi-finger/ic_join.png b/res/drawable-mdpi-finger/ic_join.png
new file mode 100644
index 0000000..177a582
--- /dev/null
+++ b/res/drawable-mdpi-finger/ic_join.png
Binary files differ
diff --git a/res/drawable-mdpi/bg_infobar_new.9.png b/res/drawable-mdpi/bg_infobar_new.9.png
new file mode 100644
index 0000000..f3a83d4
--- /dev/null
+++ b/res/drawable-mdpi/bg_infobar_new.9.png
Binary files differ
diff --git a/res/layout-finger/contact_card_layout.xml b/res/layout-finger/contact_card_layout.xml
index fe931ec..3f090f5 100644
--- a/res/layout-finger/contact_card_layout.xml
+++ b/res/layout-finger/contact_card_layout.xml
@@ -36,16 +36,6 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
- <TextView android:id="@+id/account_name"
- style="?android:attr/listSeparatorTextViewStyle"
- android:textColor="@*android:color/dim_foreground_dark"
- android:textSize="12sp"
- android:textStyle="normal"
- android:background="@drawable/section_dark"
- android:paddingLeft="7dp"
- android:gravity="left|center_vertical"
- android:visibility="gone" />
-
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="0dip"
diff --git a/res/layout-finger/contacts_list_content_join.xml b/res/layout-finger/contacts_list_content_join.xml
index ce82d2c..95f9c20 100644
--- a/res/layout-finger/contacts_list_content_join.xml
+++ b/res/layout-finger/contacts_list_content_join.xml
@@ -25,14 +25,15 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@*android:drawable/title_bar_medium"
- android:padding="5dip"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
android:gravity="center_vertical"
>
<ImageView
android:layout_width="48dip"
android:layout_height="48dip"
- android:src="@drawable/ic_menu_merge"
+ android:src="@drawable/ic_join"
android:gravity="center"
android:scaleType="fitCenter"
/>
@@ -48,9 +49,11 @@
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
+ android:id="@+id/join_contact_blurb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:text="@string/blurbJoinContactDataWith"
+ android:layout_marginTop="-2dip"
+ android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
</LinearLayout>
diff --git a/res/layout-finger/tab_account_name.xml b/res/layout-finger/tab_account_name.xml
new file mode 100644
index 0000000..dc99af1
--- /dev/null
+++ b/res/layout-finger/tab_account_name.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- looks like Widget.TextView.ListSeparator -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/account_name"
+ android:background="@drawable/bg_infobar_new"
+ android:layout_width="fill_parent"
+ android:layout_height="@dimen/account_name_height"
+ android:layout_below="@+id/tab_scroll_view"
+ android:textStyle="normal"
+ android:textColor="@*android:color/dim_foreground_dark"
+ android:textSize="12sp"
+ android:gravity="left|center_vertical"
+ android:paddingLeft="7dip"
+/>
diff --git a/res/layout-finger/tab_layout.xml b/res/layout-finger/tab_layout.xml
index 23359b7..9a793c3 100644
--- a/res/layout-finger/tab_layout.xml
+++ b/res/layout-finger/tab_layout.xml
@@ -15,6 +15,7 @@
-->
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/tab_scroll_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
diff --git a/res/layout-finger/total_contacts.xml b/res/layout-finger/total_contacts.xml
index 1221ef3..ab15ce1 100644
--- a/res/layout-finger/total_contacts.xml
+++ b/res/layout-finger/total_contacts.xml
@@ -24,6 +24,5 @@
android:textStyle="normal"
android:background="@drawable/section_dark"
android:paddingLeft="7dp"
- android:gravity="left|center_vertical"
- android:visibility="gone"
+ android:gravity="center|center_vertical"
/>
\ No newline at end of file
diff --git a/res/layout/act_edit.xml b/res/layout/act_edit.xml
index 47f1454..250a0e1 100644
--- a/res/layout/act_edit.xml
+++ b/res/layout/act_edit.xml
@@ -37,16 +37,6 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
- <TextView android:id="@+id/account_name"
- style="?android:attr/listSeparatorTextViewStyle"
- android:textColor="@*android:color/dim_foreground_dark"
- android:textSize="12sp"
- android:textStyle="normal"
- android:background="@drawable/section_dark"
- android:paddingLeft="7dp"
- android:gravity="left|center_vertical"
- android:visibility="gone" />
-
<include
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0742250..4361fd4 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -20,4 +20,5 @@
<!-- The height of the ScrollingTabWidget -->
<dimen name="tab_height">40dip</dimen>
+ <dimen name="account_name_height">25dip</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fdbaab6..da7bb88 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -139,11 +139,10 @@
<string name="titleJoinAggregate">Join contact</string>
<!-- Heading of the Join Contact screen -->
- <string name="titleJoinContactDataWith">Join contact data with:</string>
+ <string name="titleJoinContactDataWith">Join contacts</string>
<!-- Info blurb on the Join Contact screen -->
- <string name="blurbJoinContactDataWith">Contact data will be combined with
- another contact selected from the list.</string>
+ <string name="blurbJoinContactDataWith">Select the contact you want to join with <xliff:g id="name">%s</xliff:g>.</string>
<!-- List separator for the Join Contact list: Suggestions -->
<string name="separatorJoinAggregateSuggestions">Suggestions</string>
@@ -334,7 +333,7 @@
<string name="showFilterPhonesDescrip">Only display contacts that have phone numbers</string>
<!-- The header over the list of all contacts groups -->
- <string name="headerContactGroups">Contact groups</string>
+ <string name="headerContactGroups">Choose contacts to display</string>
<!-- The description of a group with the total number of contacts -->
<plurals name="groupDescrip">
@@ -361,8 +360,8 @@
<!-- Displayed in a spinner dialog after the user creates a contact and it's being saved to the database -->
<string name="savingContact">Saving contact\u2026</string>
- <!-- Displayed in a spinner dialog as user changes to display groups are saved -->
- <string name="savingDisplayGroups">Saving display groups\u2026</string>
+ <!-- Displayed in a spinner dialog as user changes to display options are saved -->
+ <string name="savingDisplayGroups">Saving display options\u2026</string>
<!-- Toast displayed when a contact is created -->
<string name="contactCreatedToast">Contact created.</string>
@@ -969,9 +968,12 @@
<string name="dialog_sync_add">Add sync group</string>
<string name="display_more_groups">More groups\u2026</string>
+ <!-- List title for a special contacts group that covers all contacts.-->
+ <string name="display_ungrouped">All Other Contacts</string>
+
<!-- List title for a special contacts group that covers all contacts that
- aren't members of any other group. -->
- <string name="display_ungrouped">(Ungrouped contacts)</string>
+ aren't members of any other group. -->
+ <string name="display_all_contacts">All Contacts</string>
<!-- Warning message given to users just before they remove a currently syncing
group that would also cause all ungrouped contacts to stop syncing. -->
@@ -1153,6 +1155,6 @@
<string name="split_explanation">Make this data its own contact.</string>
<!-- Formatting string for account name -->
- <string name="account_name_format">From account: <xliff:g id="account" example="user@gmail.com">%s</xliff:g></string>
+ <string name="account_name_format">From <xliff:g id="source" example="Gmail">%1$s</xliff:g> account: <xliff:g id="account" example="user@gmail.com">%2$s</xliff:g></string>
</resources>
diff --git a/src/com/android/contacts/Collapser.java b/src/com/android/contacts/Collapser.java
index db1da1f..3872dfd 100644
--- a/src/com/android/contacts/Collapser.java
+++ b/src/com/android/contacts/Collapser.java
@@ -39,38 +39,42 @@
*/
public interface Collapsible<T> {
public boolean collapseWith(T t);
- public String getCollapseKey();
+ public boolean shouldCollapseWith(T t);
}
/**
* Collapses a list of Collapsible items into a list of collapsed items. Items are collapsed
- * if they produce equal collapseKeys {@Link Collapsible#getCollapseKey()}, and are collapsed
- * through the {@Link Collapsible#doCollapseWith(Object)} function implemented by the data item.
+ * if {@link Collapsible#shouldCollapseWith(Object) return strue, and are collapsed
+ * through the {@Link Collapsible#collapseWith(Object)} function implemented by the data item.
*
* @param list ArrayList of Objects of type <T extends Collapsible<T>> to be collapsed.
*/
public static <T extends Collapsible<T>> void collapseList(ArrayList<T> list) {
- HashMap<String, T> collapseMap = new HashMap<String, T>();
- ArrayList<String> collapseKeys = new ArrayList<String>();
int listSize = list.size();
- for (int j = 0; j < listSize; j++) {
- T entry = list.get(j);
- String collapseKey = entry.getCollapseKey();
- if (!collapseMap.containsKey(collapseKey)) {
- collapseMap.put(collapseKey, entry);
- collapseKeys.add(collapseKey);
- } else {
- collapseMap.get(collapseKey).collapseWith(entry);
+
+ for (int i = 0; i < listSize; i++) {
+ T iItem = list.get(i);
+ if (iItem != null) {
+ for (int j = i + 1; j < listSize; j++) {
+ T jItem = list.get(j);
+ if (jItem != null) {
+ if (iItem.shouldCollapseWith(jItem)) {
+ iItem.collapseWith(jItem);
+ list.set(j, null);
+ }
+ }
+ }
}
}
- if (collapseKeys.size() < listSize) {
- list.clear();
- Iterator<String> itr = collapseKeys.iterator();
- while (itr.hasNext()) {
- list.add(collapseMap.get(itr.next()));
+ // Remove the null items
+ Iterator<T> itr = list.iterator();
+ while (itr.hasNext()) {
+ if (itr.next() == null) {
+ itr.remove();
}
}
+
}
}
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index cc2f02f..aa6654d 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -86,7 +86,6 @@
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
@@ -161,6 +160,14 @@
*/
public static final String EXTRA_AGGREGATE_ID =
"com.android.contacts.action.AGGREGATE_ID";
+ /**
+ * Used with {@link #JOIN_AGGREGATE} to give it the name of the aggregation target.
+ * <p>
+ * Type: STRING
+ */
+ public static final String EXTRA_AGGREGATE_NAME =
+ "com.android.contacts.action.AGGREGATE_NAME";
+
public static final String AUTHORITIES_FILTER_KEY = "authorities";
@@ -551,6 +558,15 @@
if (mMode == MODE_JOIN_CONTACT) {
setContentView(R.layout.contacts_list_content_join);
+ TextView blurbView = (TextView)findViewById(R.id.join_contact_blurb);
+ String contactName = intent.getStringExtra(EXTRA_AGGREGATE_NAME);
+ if (contactName == null) {
+ contactName = "";
+ }
+
+ String blurb = getString(R.string.blurbJoinContactDataWith, contactName);
+ blurbView.setText(blurb);
+
} else {
setContentView(R.layout.contacts_list_content);
}
@@ -567,14 +583,9 @@
list.setTextFilterEnabled(true);
}
- final LayoutInflater inflater = getLayoutInflater();
- if ((mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
- View totalContacts = inflater.inflate(R.layout.total_contacts, list, false);
- list.addHeaderView(totalContacts);
- }
-
if ((mMode & MODE_MASK_CREATE_NEW) != 0) {
// Add the header for creating a new contact
+ final LayoutInflater inflater = getLayoutInflater();
View header = inflater.inflate(R.layout.create_new_contact, list, false);
list.addHeaderView(header);
}
@@ -586,11 +597,6 @@
setListAdapter(mAdapter);
getListView().setOnScrollListener(mAdapter);
- if ((mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
- TextView totalContacts = (TextView) findViewById(R.id.totalContactsText);
- totalContacts.setVisibility(View.VISIBLE);
- }
-
// We manually save/restore the listview state
list.setSaveEnabled(false);
@@ -830,6 +836,10 @@
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
+ case R.string.import_from_sim:
+ case R.string.import_from_sdcard: {
+ return AccountSelectionUtil.getSelectAccountDialog(this, id);
+ }
case R.id.dialog_sdcard_not_found: {
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle(R.string.no_sdcard_title)
@@ -1091,13 +1101,6 @@
getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(mList.getWindowToken(), 0);
- if ((mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
- if (position == 0) {
- return;
- }
- position--;
- }
-
if (mMode == MODE_INSERT_OR_EDIT_CONTACT) {
Intent intent;
if (position == 0) {
@@ -1541,7 +1544,10 @@
mQueryHandler.setLoadingJoinSuggestions(false);
String[] projection = getProjectionForQuery();
- Uri uri = getUriToQuery();
+ Uri uri = getUriToQuery().buildUpon()
+ .appendQueryParameter(ContactsContract.REQUESTING_PACKAGE_PARAM_KEY,
+ getCallingPackage())
+ .build();
// Kick off the new query
switch (mMode) {
@@ -1754,7 +1760,7 @@
getColumnIndex(Phone.IS_SUPER_PRIMARY)) != 0) {
// Found super primary, call it.
phone = phonesCursor.
- getString(phonesCursor.getColumnIndex(Phone.NUMBER));
+ getString(phonesCursor.getColumnIndex(Phone.NUMBER));
break;
}
}
@@ -2068,6 +2074,9 @@
@Override
public int getItemViewType(int position) {
+ if (position == 0 && (mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
+ return IGNORE_ITEM_VIEW_TYPE;
+ }
if (getSeparatorId(position) != 0) {
// We don't want the separator view to be recycled.
return IGNORE_ITEM_VIEW_TYPE;
@@ -2082,6 +2091,17 @@
"this should only be called when the cursor is valid");
}
+ // handle the total contacts item
+ if (position == 0 && (mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
+ final LayoutInflater inflater = getLayoutInflater();
+ TextView totalContacts = (TextView) inflater.inflate(R.layout.total_contacts,
+ parent, false);
+ int stringId = mDisplayOnlyPhones ? R.string.listTotalPhoneContacts
+ : R.string.listTotalAllContacts;
+ totalContacts.setText(getString(stringId, getCount()));
+ return totalContacts;
+ }
+
// Handle the separator specially
int separatorId = getSeparatorId(position);
if (separatorId != 0) {
@@ -2377,12 +2397,6 @@
}
super.changeCursor(cursor);
- if ((mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
- TextView totalContacts = (TextView) findViewById(R.id.totalContactsText);
- int stringId = mDisplayOnlyPhones
- ? R.string.listTotalPhoneContacts : R.string.listTotalAllContacts;
- totalContacts.setText(getString(stringId, cursorCount));
- }
// Update the indexer for the fast scroll widget
updateIndexer(cursor);
}
@@ -2494,6 +2508,12 @@
@Override
public boolean isEnabled(int position) {
+ if ((mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
+ if (position == 0) {
+ return false;
+ }
+ position--;
+ }
if (mSuggestionsCursorCount > 0) {
return position != 0 && position != mSuggestionsCursorCount + 1;
}
@@ -2516,6 +2536,9 @@
}
private int getRealPosition(int pos) {
+ if ((mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0) {
+ pos--;
+ }
if (mSuggestionsCursorCount != 0) {
// When showing suggestions, we have 2 additional list items: the "Suggestions"
// and "All contacts" separators.
diff --git a/src/com/android/contacts/PhoneDisambigDialog.java b/src/com/android/contacts/PhoneDisambigDialog.java
index 58d3721..b727c77 100644
--- a/src/com/android/contacts/PhoneDisambigDialog.java
+++ b/src/com/android/contacts/PhoneDisambigDialog.java
@@ -17,8 +17,9 @@
package com.android.contacts;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.List;
+
+import com.android.contacts.Collapser.Collapsible;
import android.app.AlertDialog;
import android.content.ContentUris;
@@ -28,12 +29,13 @@
import android.database.Cursor;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.telephony.PhoneNumberUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
-import android.widget.SimpleCursorAdapter;
+import android.widget.ListAdapter;
/**
* Class used for displaying a dialog with a list of phone numbers of which
@@ -47,6 +49,8 @@
private AlertDialog mDialog;
private boolean mSendSms;
private Cursor mPhonesCursor;
+ private ListAdapter mPhonesAdapter;
+ private ArrayList<PhoneItem> mPhoneItemList;
public PhoneDisambigDialog(Context context, Cursor phonesCursor) {
this(context, phonesCursor, false /*make call*/);
@@ -57,6 +61,11 @@
mSendSms = sendSms;
mPhonesCursor = phonesCursor;
+ mPhoneItemList = makePhoneItemsList(phonesCursor);
+ Collapser.collapseList(mPhoneItemList);
+
+ mPhonesAdapter = new PhonesAdapter(mContext, mPhoneItemList);
+
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View setPrimaryView = inflater.
@@ -66,9 +75,10 @@
// Need to show disambig dialogue.
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext).
- setCursor(mPhonesCursor, this, Phone.NUMBER).
- setTitle(sendSms ? R.string.sms_disambig_title : R.string.call_disambig_title).
- setView(setPrimaryView);
+ setAdapter(mPhonesAdapter, this).
+ setTitle(sendSms ?
+ R.string.sms_disambig_title : R.string.call_disambig_title).
+ setView(setPrimaryView);
mDialog = dialogBuilder.create();
}
@@ -77,18 +87,25 @@
* Show the dialog.
*/
public void show() {
+ if (mPhoneItemList.size() == 1) {
+ // If there is only one after collapse, just select it, and close;
+ onClick(mDialog, 0);
+ return;
+ }
mDialog.show();
}
public void onClick(DialogInterface dialog, int which) {
- if (mPhonesCursor.moveToPosition(which)) {
- long id = mPhonesCursor.getLong(mPhonesCursor.getColumnIndex(Data._ID));
- String phone = mPhonesCursor.getString(mPhonesCursor.getColumnIndex(Phone.NUMBER));
+ if (mPhoneItemList.size() > which && which >= 0) {
+ PhoneItem phoneItem = mPhoneItemList.get(which);
+ long id = phoneItem.id;
+ String phone = phoneItem.phoneNumber;
+
if (mMakePrimary) {
ContentValues values = new ContentValues(1);
values.put(Data.IS_SUPER_PRIMARY, 1);
- mContext.getContentResolver().update(ContentUris.withAppendedId(Data.CONTENT_URI, id),
- values, null, null);
+ mContext.getContentResolver().update(ContentUris.
+ withAppendedId(Data.CONTENT_URI, id), values, null, null);
}
if (mSendSms) {
@@ -108,4 +125,56 @@
public void onDismiss(DialogInterface dialog) {
mPhonesCursor.close();
}
+
+ private static class PhonesAdapter extends ArrayAdapter<PhoneItem> {
+
+ public PhonesAdapter(Context context, List<PhoneItem> objects) {
+ super(context, android.R.layout.simple_dropdown_item_1line,
+ android.R.id.text1, objects);
+ }
+ }
+
+ private class PhoneItem implements Collapsible<PhoneItem> {
+
+ String phoneNumber;
+ long id;
+
+ public PhoneItem(String newPhoneNumber, long newId) {
+ phoneNumber = newPhoneNumber;
+ id = newId;
+ }
+
+ public boolean collapseWith(PhoneItem phoneItem) {
+ if (!shouldCollapseWith(phoneItem)) {
+ return false;
+ }
+ // Just keep the number and id we already have.
+ return true;
+ }
+
+ public boolean shouldCollapseWith(PhoneItem phoneItem) {
+ if (PhoneNumberUtils.compare(PhoneDisambigDialog.this.mContext,
+ phoneNumber, phoneItem.phoneNumber)) {
+ return true;
+ }
+ return false;
+ }
+
+ public String toString() {
+ return phoneNumber;
+ }
+ }
+
+ private ArrayList<PhoneItem> makePhoneItemsList(Cursor phonesCursor) {
+ ArrayList<PhoneItem> phoneList = new ArrayList<PhoneItem>();
+
+ phonesCursor.moveToPosition(-1);
+ while (phonesCursor.moveToNext()) {
+ long id = phonesCursor.getLong(phonesCursor.getColumnIndex(Data._ID));
+ String phone = phonesCursor.getString(phonesCursor.getColumnIndex(Phone.NUMBER));
+ phoneList.add(new PhoneItem(phone, id));
+ }
+
+ return phoneList;
+ }
}
diff --git a/src/com/android/contacts/ScrollingTabWidget.java b/src/com/android/contacts/ScrollingTabWidget.java
index 6974a6e..b45abe4 100644
--- a/src/com/android/contacts/ScrollingTabWidget.java
+++ b/src/com/android/contacts/ScrollingTabWidget.java
@@ -18,12 +18,7 @@
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -32,7 +27,6 @@
import android.view.View.OnFocusChangeListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.RelativeLayout;
/*
@@ -82,6 +76,7 @@
mTabsScrollWrapper = (HorizontalScrollView) mInflater.inflate(
R.layout.tab_layout, this, false);
mTabsView = (TabStripView) mTabsScrollWrapper.findViewById(android.R.id.tabs);
+ View accountNameView = mInflater.inflate(R.layout.tab_account_name, this, false);
mLeftArrowView.setVisibility(View.INVISIBLE);
mRightArrowView.setVisibility(View.INVISIBLE);
@@ -89,6 +84,7 @@
addView(mTabsScrollWrapper);
addView(mLeftArrowView);
addView(mRightArrowView);
+ addView(accountNameView);
}
@Override
diff --git a/src/com/android/contacts/TwelveKeyDialer.java b/src/com/android/contacts/TwelveKeyDialer.java
index d07d785..58ba9d8 100644
--- a/src/com/android/contacts/TwelveKeyDialer.java
+++ b/src/com/android/contacts/TwelveKeyDialer.java
@@ -1028,6 +1028,8 @@
digits.replace(selectionStart, selectionStart, newDigits);
} else {
digits.replace(selectionStart, selectionEnd, newDigits);
+ // Unselect: back to a regular cursor, just pass the character inserted.
+ mDigits.setSelection(selectionStart + 1);
}
} else {
int len = mDigits.length();
diff --git a/src/com/android/contacts/ViewContactActivity.java b/src/com/android/contacts/ViewContactActivity.java
index 8275686..8172423 100644
--- a/src/com/android/contacts/ViewContactActivity.java
+++ b/src/com/android/contacts/ViewContactActivity.java
@@ -215,9 +215,9 @@
mTabWidget.setTabSelectionListener(this);
mTabWidget.setVisibility(View.GONE);
mTabsVisible = false;
+ mAccountName = (TextView) mTabWidget.findViewById(R.id.account_name);
mBelowHeader = findViewById(R.id.below_header);
- mAccountName = (TextView) findViewById(R.id.account_name);
mTabRawContactIdMap = new SparseArray<Long>();
@@ -397,12 +397,14 @@
return;
}
- float tabHeight = getResources().getDimension(R.dimen.tab_height);
+ final Resources resources = getResources();
+ final float tabHeight = resources.getDimension(R.dimen.tab_height)
+ + resources.getDimension(R.dimen.account_name_height);
if (show) {
TranslateAnimation showAnimation = new TranslateAnimation(
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, -tabHeight, Animation.ABSOLUTE, 0);
- showAnimation.setDuration(getResources().getInteger(
+ showAnimation.setDuration(resources.getInteger(
android.R.integer.config_longAnimTime));
showAnimation.setAnimationListener(new AnimationListener() {
@@ -428,7 +430,7 @@
TranslateAnimation hideTabsAnimation = new TranslateAnimation(
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -tabHeight);
- hideTabsAnimation.setDuration(getResources().getInteger(
+ hideTabsAnimation.setDuration(resources.getInteger(
android.R.integer.config_longAnimTime));
hideTabsAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
@@ -446,7 +448,7 @@
TranslateAnimation hideListAnimation = new TranslateAnimation(
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, tabHeight, Animation.ABSOLUTE, 0);
- hideListAnimation.setDuration(getResources().getInteger(
+ hideListAnimation.setDuration(resources.getInteger(
android.R.integer.config_longAnimTime));
@@ -761,8 +763,15 @@
* Shows a list of aggregates that can be joined into the currently viewed aggregate.
*/
public void showJoinAggregateActivity() {
+ String displayName = null;
+ if (mCursor.moveToFirst()) {
+ displayName = mCursor.getString(0);
+ }
Intent intent = new Intent(ContactsListActivity.JOIN_AGGREGATE);
intent.putExtra(ContactsListActivity.EXTRA_AGGREGATE_ID, ContentUris.parseId(mUri));
+ if (displayName != null) {
+ intent.putExtra(ContactsListActivity.EXTRA_AGGREGATE_NAME, displayName);
+ }
startActivityForResult(intent, REQUEST_JOIN_CONTACT);
}
@@ -945,13 +954,11 @@
continue;
}
- if (mTabsVisible) {
- final String accountName = entValues.getAsString(RawContacts.ACCOUNT_NAME);
- mAccountName.setText(getString(R.string.account_name_format, accountName));
- mAccountName.setVisibility(View.VISIBLE);
- } else {
- mAccountName.setVisibility(View.GONE);
- }
+ final ContactsSource source = sources.getInflatedSource(accountType,
+ ContactsSource.LEVEL_SUMMARY);
+ final String accountName = entValues.getAsString(RawContacts.ACCOUNT_NAME);
+ mAccountName.setText(getString(R.string.account_name_format,
+ source.getDisplayLabel(this), accountName));
for (NamedContentValues subValue : entity.getSubValues()) {
ViewEntry entry = new ViewEntry();
@@ -1154,7 +1161,7 @@
/**
* A basic structure with the data for a contact entry in the list.
*/
- static class ViewEntry extends ContactEntryAdapter.Entry implements Collapsible<ViewEntry> {
+ class ViewEntry extends ContactEntryAdapter.Entry implements Collapsible<ViewEntry> {
public String resPackageName = null;
public int actionIcon = -1;
public boolean isPrimary = false;
@@ -1169,7 +1176,7 @@
public boolean collapseWith(ViewEntry entry) {
// assert equal collapse keys
- if (!getCollapseKey().equals(entry.getCollapseKey())) {
+ if (!shouldCollapseWith(entry)) {
return false;
}
@@ -1201,16 +1208,43 @@
return true;
}
- public String getCollapseKey() {
- StringBuilder hashSb = new StringBuilder();
- hashSb.append(data);
- hashSb.append(mimetype);
- hashSb.append((intent != null && intent.getAction() != null)
- ? intent.getAction() : "");
- hashSb.append((secondaryIntent != null && secondaryIntent.getAction() != null)
- ? secondaryIntent.getAction() : "");
- hashSb.append(actionIcon);
- return hashSb.toString();
+ public boolean shouldCollapseWith(ViewEntry entry) {
+ if (entry == null) {
+ return false;
+ }
+
+ if (Phone.CONTENT_ITEM_TYPE.equals(mimetype)
+ && Phone.CONTENT_ITEM_TYPE.equals(entry.mimetype)) {
+ if (!PhoneNumberUtils.compare(ViewContactActivity.this, data, entry.data)) {
+ return false;
+ }
+ } else {
+ if (!equals(data, entry.data)) {
+ return false;
+ }
+ }
+
+ if (!equals(mimetype, entry.mimetype)
+ || !intentCollapsible(intent, entry.intent)
+ || !intentCollapsible(secondaryIntent, entry.secondaryIntent)
+ || actionIcon != entry.actionIcon) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean equals(Object a, Object b) {
+ return a==b || (a != null && a.equals(b));
+ }
+
+ private boolean intentCollapsible(Intent a, Intent b) {
+ if (a == b) {
+ return true;
+ } else if ((a != null && b != null) && equals(a.getAction(), b.getAction())) {
+ return true;
+ }
+ return false;
}
}
diff --git a/src/com/android/contacts/ui/DisplayGroupsActivity.java b/src/com/android/contacts/ui/DisplayGroupsActivity.java
index dcbe0f6..7bd7b9d 100644
--- a/src/com/android/contacts/ui/DisplayGroupsActivity.java
+++ b/src/com/android/contacts/ui/DisplayGroupsActivity.java
@@ -187,6 +187,7 @@
*/
protected static class GroupDelta extends ValuesDelta {
private boolean mUngrouped = false;
+ private boolean mAccountHasGroups;
private GroupDelta() {
super();
@@ -197,7 +198,7 @@
* {@link Settings#ACCOUNT_NAME} and {@link Settings#ACCOUNT_TYPE}.
*/
public static GroupDelta fromSettings(ContentResolver resolver, String accountName,
- String accountType) {
+ String accountType, boolean accountHasGroups) {
final Uri settingsUri = Settings.CONTENT_URI.buildUpon()
.appendQueryParameter(Settings.ACCOUNT_NAME, accountName)
.appendQueryParameter(Settings.ACCOUNT_TYPE, accountType).build();
@@ -214,12 +215,12 @@
// Read existing values when present
values.put(Settings.SHOULD_SYNC, cursor.getInt(0));
values.put(Settings.UNGROUPED_VISIBLE, cursor.getInt(1));
- return fromBefore(values).setUngrouped();
+ return fromBefore(values).setUngrouped(accountHasGroups);
} else {
// Nothing found, so treat as create
values.put(Settings.SHOULD_SYNC, DEFAULT_SHOULD_SYNC);
values.put(Settings.UNGROUPED_VISIBLE, DEFAULT_VISIBLE);
- return fromAfter(values).setUngrouped();
+ return fromAfter(values).setUngrouped(accountHasGroups);
}
} finally {
if (cursor != null) cursor.close();
@@ -240,8 +241,9 @@
return entry;
}
- protected GroupDelta setUngrouped() {
+ protected GroupDelta setUngrouped(boolean accountHasGroups) {
mUngrouped = true;
+ mAccountHasGroups = accountHasGroups;
return this;
}
@@ -270,7 +272,11 @@
public CharSequence getTitle(Context context) {
if (mUngrouped) {
- return context.getText(R.string.display_ungrouped);
+ if (mAccountHasGroups) {
+ return context.getText(R.string.display_ungrouped);
+ } else {
+ return context.getText(R.string.display_all_contacts);
+ }
} else {
final Integer titleRes = getAsInteger(Groups.TITLE_RES);
if (titleRes != null) {
@@ -359,9 +365,7 @@
mName = accountName;
mType = accountType;
- // Create single entry handling ungrouped status
- mUngrouped = GroupDelta.fromSettings(resolver, accountName, accountType);
- addGroup(mUngrouped);
+ boolean hasGroups = false;
final Uri groupsUri = Groups.CONTENT_URI.buildUpon()
.appendQueryParameter(Groups.ACCOUNT_NAME, accountName)
@@ -374,12 +378,17 @@
final ContentValues values = iterator.next().getEntityValues();
final GroupDelta group = GroupDelta.fromBefore(values);
addGroup(group);
+ hasGroups = true;
}
} catch (RemoteException e) {
Log.w(TAG, "Problem reading groups: " + e.toString());
} finally {
if (iterator != null) iterator.close();
}
+
+ // Create single entry handling ungrouped status
+ mUngrouped = GroupDelta.fromSettings(resolver, accountName, accountType, hasGroups);
+ addGroup(mUngrouped);
}
/**
diff --git a/src/com/android/contacts/ui/EditContactActivity.java b/src/com/android/contacts/ui/EditContactActivity.java
index bb10a8a..450f4a9 100644
--- a/src/com/android/contacts/ui/EditContactActivity.java
+++ b/src/com/android/contacts/ui/EditContactActivity.java
@@ -121,12 +121,12 @@
// Header bar is filled later after queries finish
mHeader = (ContactHeaderWidget)this.findViewById(R.id.contact_header_widget);
mHeader.setContactHeaderListener(this);
- mHeader.showStar(true);
+ mHeader.showStar(false);
mHeader.enableClickListeners();
mTabWidget = (ScrollingTabWidget)this.findViewById(R.id.tab_widget);
mTabWidget.setTabSelectionListener(this);
- mAccountName = (TextView)this.findViewById(R.id.account_name);
+ mAccountName = (TextView)mTabWidget.findViewById(R.id.account_name);
// Build editor and listen for photo requests
mEditor = (ContactEditorView)this.findViewById(android.R.id.tabcontent);
@@ -181,7 +181,7 @@
}
} else if (android.provider.Contacts.AUTHORITY.equals(authority)) {
final long rawContactId = ContentUris.parseId(data);
- selection = RawContacts._ID + "=" + rawContactId;
+ selection = Data.RAW_CONTACT_ID + "=" + rawContactId;
}
target.mQuerySelection = selection;
@@ -402,7 +402,8 @@
final ContactsSource source = sources.getInflatedSource(accountType,
ContactsSource.LEVEL_CONSTRAINTS);
- mAccountName.setText(getString(R.string.account_name_format, accountName));
+ mAccountName.setText(getString(R.string.account_name_format,
+ source.getDisplayLabel(this), accountName));
mAccountName.setVisibility(View.VISIBLE);
// Assign editor state based on entity and source
diff --git a/src/com/android/contacts/util/AccountSelectionUtil.java b/src/com/android/contacts/util/AccountSelectionUtil.java
index 86c04eb..cf83581 100644
--- a/src/com/android/contacts/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/util/AccountSelectionUtil.java
@@ -24,6 +24,7 @@
import android.accounts.Account;
import android.app.AlertDialog;
+import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -70,11 +71,11 @@
}
}
- public static void displaySelectAccountDialog(Context context, int resId) {
- displaySelectAccountDialog(context, resId, null);
+ public static Dialog getSelectAccountDialog(Context context, int resId) {
+ return getSelectAccountDialog(context, resId, null);
}
- public static void displaySelectAccountDialog(Context context, int resId,
+ public static Dialog getSelectAccountDialog(Context context, int resId,
DialogInterface.OnCancelListener onCancelListener) {
final Sources sources = Sources.getInstance(context);
final List<Account> writableAccountList = sources.getAccounts(true);
@@ -119,11 +120,11 @@
AccountSelectedListener accountSelectedListener =
new AccountSelectedListener(context, writableAccountList, resId);
- new AlertDialog.Builder(context)
+ return new AlertDialog.Builder(context)
.setTitle(R.string.dialog_new_contact_account)
.setSingleChoiceItems(accountAdapter, 0, accountSelectedListener)
.setOnCancelListener(accountSelectedListener)
- .show();
+ .create();
}
public static void doImport(Context context, int resId, Account account) {