diff options
author | Chiao Cheng <chiaocheng@google.com> | 2012-12-04 14:59:50 -0800 |
---|---|---|
committer | Chiao Cheng <chiaocheng@google.com> | 2012-12-04 14:59:50 -0800 |
commit | e420de7fca9005d7084be275f268962a14094a22 (patch) | |
tree | ff517d8f1c161c94c43ca594ff159686b3e117d1 | |
parent | 756457c831b7a2c30166b6e7af8319ad04112e7d (diff) | |
download | android_packages_apps_ContactsCommon-e420de7fca9005d7084be275f268962a14094a22.tar.gz android_packages_apps_ContactsCommon-e420de7fca9005d7084be275f268962a14094a22.tar.bz2 android_packages_apps_ContactsCommon-e420de7fca9005d7084be275f268962a14094a22.zip |
Moving SelectAccountDialogFragment to ContactsCommon.
In preparation to move ImportExportDialogFragment to common.
Also moved a few more string resources left out from previous move.
Bug: 6993891
Change-Id: I978e490d256cf783db91b52bca46f4a1c678e415
-rw-r--r-- | res/layout/account_selector_list_item.xml | 51 | ||||
-rw-r--r-- | res/values/dimens.xml | 3 | ||||
-rw-r--r-- | res/values/donottranslate_config.xml | 12 | ||||
-rw-r--r-- | res/values/strings.xml | 80 | ||||
-rw-r--r-- | src/com/android/contacts/common/editor/SelectAccountDialogFragment.java | 121 | ||||
-rw-r--r-- | src/com/android/contacts/common/util/AccountsListAdapter.java | 123 |
6 files changed, 390 insertions, 0 deletions
diff --git a/res/layout/account_selector_list_item.xml b/res/layout/account_selector_list_item.xml new file mode 100644 index 00000000..4cba3e96 --- /dev/null +++ b/res/layout/account_selector_list_item.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="?android:attr/listPreferredItemHeight" + android:orientation="horizontal"> + <ImageView android:id="@android:id/icon" + android:layout_width="@dimen/detail_network_icon_size" + android:layout_height="@dimen/detail_network_icon_size" + android:layout_margin="8dip" + android:layout_gravity="center_vertical" /> + + <LinearLayout + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1" + android:orientation="vertical" + android:layout_gravity="center_vertical"> + + <TextView android:id="@android:id/text1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginRight="8dip" + android:textAppearance="?android:attr/textAppearanceMedium" + android:singleLine="true" + android:ellipsize="end"/> + + <TextView android:id="@android:id/text2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginRight="8dip" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary" + android:singleLine="true" + android:ellipsize="end"/> + </LinearLayout> +</LinearLayout> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 43c29e87..5fd33903 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -83,4 +83,7 @@ <!-- Extra vertical padding for darkened background behind shortcut icon overlay text --> <dimen name="shortcut_overlay_text_background_padding">1dp</dimen> + + <!-- Width of height of an icon from a third-party app in the networks section of the contact card. --> + <dimen name="detail_network_icon_size">32dip</dimen> </resources> diff --git a/res/values/donottranslate_config.xml b/res/values/donottranslate_config.xml index 0552d850..f2628cae 100644 --- a/res/values/donottranslate_config.xml +++ b/res/values/donottranslate_config.xml @@ -15,6 +15,18 @@ --> <resources> + <!-- Flag indicating whether Contacts app is allowed to import contacts from SDCard --> + <bool name="config_allow_import_from_sdcard">true</bool> + <!-- If true, all vcard files are imported from SDCard without asking a user. + If not, dialog shows to let the user to select whether all vcard files are imported or not. + If the user selects "not", then the application ask the user to select a file.--> + <bool name="config_import_all_vcard_from_sdcard_automatically">false</bool> + <!-- If true, vcard importer shows a dialog which asks the user whether the user wants + to import all vcard files in SDCard or select one vcard file. If false, the dialog is + skipped and the importer asks the user to choose one vcard file. + If config_import_all_vcard_from_sdcard_automatically is set true, this configuration + is ignored. --> + <bool name="config_allow_users_select_all_vcard_import">true</bool> <!-- If true, an option is shown in Display Options UI to choose a sort order --> <bool name="config_sort_order_user_changeable">true</bool> diff --git a/res/values/strings.xml b/res/values/strings.xml index 8ad6d5bd..f2a8e440 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -454,6 +454,42 @@ a ren't members of any other group. [CHAR LIMIT=25] --> Some exact reason must follow this. [CHAR LIMIT=NONE] --> <string name="fail_reason_error_occurred_during_export">An error occurred during export: \"<xliff:g id="exact_reason">%s</xliff:g>\".</string> + <!-- The failed reason shown when the given file name is too long for the system. + The length limit of each file is different in each Android device, so we don't need to + mention it here. [CHAR LIMIT=NONE] --> + <string name="fail_reason_too_long_filename">Required filename is too long (\"<xliff:g id="filename">%s</xliff:g>\").</string> + + <!-- The failed reason shown when vCard exporter could not create a file for the vCard since + there are too many files relevant to vCard. [CHAR LIMIT=NONE] --> + <string name="fail_reason_too_many_vcard" product="nosdcard">Too many vCard files are in the storage.</string> + <!-- The failed reason shown when vCard exporter could not create a file for the vCard since + there are too many files relevant to vCard. --> + <string name="fail_reason_too_many_vcard" product="default">Too many vCard files are on the SD card.</string> + + <!-- The failed reason shown when Contacts app (especially vCard importer/exporter) + emitted some I/O error. Exact reason will be appended by the system. [CHAR LIMIT=NONE] --> + <string name="fail_reason_io_error">I/O error</string> + + <!-- Failure reason show when Contacts app (especially vCard importer) encountered + low memory problem and could not proceed its import procedure. [CHAR LIMIT=NONE] --> + <string name="fail_reason_low_memory_during_import">Not enough memory. The file may be too large.</string> + + <!-- The failed reason shown when vCard parser was not able to be parsed by the current vCard + implementation. This might happen even when the input vCard is completely valid, though + we believe it is rather rare in the actual world. [CHAR LIMIT=NONE] --> + <string name="fail_reason_vcard_parse_error">Couldn\'t parse vCard for an unexpected reason.</string> + + <!-- The failed reason shown when vCard importer doesn't support the format. + This may be shown when the vCard is corrupted [CHAR LIMIT=40] --> + <string name="fail_reason_not_supported">The format isn\'t supported.</string> + + <!-- Fail reason shown when vCard importer failed to look over meta information stored in vCard file(s). --> + <string name="fail_reason_failed_to_collect_vcard_meta_info">Couldn\'t collect meta information of given vCard file(s).</string> + + <!-- The failed reason shown when the import of some of vCard files failed during multiple vCard + files import. It includes the case where all files were failed to be imported. --> + <string name="fail_reason_failed_to_read_files">One or more files couldn\'t be imported (%s).</string> + <!-- The title shown when exporting vCard is successfuly finished [CHAR LIMIT=40] --> <string name="exporting_vcard_finished_title">Finished exporting <xliff:g id="filename" example="export.vcf">%s</xliff:g>.</string> @@ -566,4 +602,48 @@ a ren't members of any other group. [CHAR LIMIT=25] --> <!-- The "file name" displayed for vCards received directly via NFC [CHAR LIMIT=16] --> <string name="nfc_vcard_file_name">Contact received over NFC</string> + <!-- Dialog title shown when a user confirms whether he/she export Contact data. [CHAR LIMIT=32] --> + <string name="confirm_export_title">Export contacts?</string> + + <!-- Dialog title shown when a user is asked to select vCard file. [CHAR LIMIT=25] --> + <string name="select_vcard_title">Choose vCard file</string> + + <!-- One of alternatives shown when the system allows a user to select how many vCard files + should be imported. This message shows only when the system is certain that there's more + than one vCard files available in the system. --> + <string name="import_one_vcard_string">Import one vCard file</string> + + <!-- One of alternatives shown when the system allows a user to select how many vCard files + should be imported. This message shows only when the system is certain that there's more + than one vCard files available in the system. --> + <string name="import_multiple_vcard_string">Import multiple vCard files</string> + + <!-- One of alternatives shown when the system allows a user to select how many vCard files + should be imported. This message shows only when the system is certain that there's more + than one vCard files available in the system. --> + <string name="import_all_vcard_string">Import all vCard files</string> + + <!-- Dialog message shown when searching VCard data from (USB) storage [CHAR LIMIT=NONE] --> + <string name="searching_vcard_message" product="nosdcard">Searching for vCard data in storage\u2026</string> + <!-- Dialog message shown when searching VCard data from SD Card. [CHAR LIMIT=NONE] --> + <string name="searching_vcard_message" product="default">Searching for vCard data on SD card\u2026</string> + + <!-- The title shown when vCard importer is caching files to be imported into local temporary + data storage. [CHAR LIMIT=40] --> + <string name="caching_vcard_title">Caching</string> + + <!-- Dialog message shown when searching VCard data failed. + An exact reason for the failure should [CHAR LIMIT=NONE] --> + <string name="scanning_sdcard_failed_message" product="nosdcard">The storage couldn\'t be scanned. (Reason: \"<xliff:g id="fail_reason">%s</xliff:g>\")</string> + <!-- Dialog message shown when searching VCard data failed. + An exact reason for the failure should [CHAR LIMIT=NONE] --> + <string name="scanning_sdcard_failed_message" product="default">The SD card couldn\'t be scanned. (Reason: \"<xliff:g id="fail_reason">%s</xliff:g>\")</string> + + <!-- The message shown while importing vCard(s). + First argument is current index of contacts to be imported. + Second argument is the total number of contacts. + Third argument is the name of a contact which is being read. + [CHAR LIMIT=20] --> + <string name="progress_notifier_message">Importing <xliff:g id="current_number">%s</xliff:g>/<xliff:g id="total_number">%s</xliff:g>: <xliff:g id="name" example="Joe Due">%s</xliff:g></string> + </resources> diff --git a/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java new file mode 100644 index 00000000..c2ebbbfa --- /dev/null +++ b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2010 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.contacts.common.editor; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.Fragment; +import android.app.FragmentManager; +import android.content.DialogInterface; +import android.os.Bundle; + +import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.util.AccountsListAdapter; +import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter; + +/** + * Shows a dialog asking the user which account to chose. + * + * The result is passed to {@code targetFragment} passed to {@link #show}. + */ +public final class SelectAccountDialogFragment extends DialogFragment { + public static final String TAG = "SelectAccountDialogFragment"; + + private static final String KEY_TITLE_RES_ID = "title_res_id"; + private static final String KEY_LIST_FILTER = "list_filter"; + private static final String KEY_EXTRA_ARGS = "extra_args"; + + public SelectAccountDialogFragment() { // All fragments must have a public default constructor. + } + + /** + * Show the dialog. + * + * @param fragmentManager {@link FragmentManager}. + * @param targetFragment {@link Fragment} that implements {@link Listener}. + * @param titleResourceId resource ID to use as the title. + * @param accountListFilter account filter. + * @param extraArgs Extra arguments, which will later be passed to + * {@link Listener#onAccountChosen}. {@code null} will be converted to + * {@link Bundle#EMPTY}. + */ + public static <F extends Fragment & Listener> void show(FragmentManager fragmentManager, + F targetFragment, int titleResourceId, + AccountListFilter accountListFilter, Bundle extraArgs) { + final Bundle args = new Bundle(); + args.putInt(KEY_TITLE_RES_ID, titleResourceId); + args.putSerializable(KEY_LIST_FILTER, accountListFilter); + args.putBundle(KEY_EXTRA_ARGS, (extraArgs == null) ? Bundle.EMPTY : extraArgs); + + final SelectAccountDialogFragment instance = new SelectAccountDialogFragment(); + instance.setArguments(args); + instance.setTargetFragment(targetFragment, 0); + instance.show(fragmentManager, null); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + final Bundle args = getArguments(); + + final AccountListFilter filter = (AccountListFilter) args.getSerializable(KEY_LIST_FILTER); + final AccountsListAdapter accountAdapter = new AccountsListAdapter(builder.getContext(), + filter); + + final DialogInterface.OnClickListener clickListener = + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + + onAccountSelected(accountAdapter.getItem(which)); + } + }; + + builder.setTitle(args.getInt(KEY_TITLE_RES_ID)); + builder.setSingleChoiceItems(accountAdapter, 0, clickListener); + final AlertDialog result = builder.create(); + return result; + } + + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + final Fragment targetFragment = getTargetFragment(); + if (targetFragment != null && targetFragment instanceof Listener) { + final Listener target = (Listener) targetFragment; + target.onAccountSelectorCancelled(); + } + } + + /** + * Calls {@link Listener#onAccountChosen} of {@code targetFragment}. + */ + private void onAccountSelected(AccountWithDataSet account) { + final Fragment targetFragment = getTargetFragment(); + if (targetFragment != null && targetFragment instanceof Listener) { + final Listener target = (Listener) targetFragment; + target.onAccountChosen(account, getArguments().getBundle(KEY_EXTRA_ARGS)); + } + } + + public interface Listener { + void onAccountChosen(AccountWithDataSet account, Bundle extraArgs); + void onAccountSelectorCancelled(); + } +} diff --git a/src/com/android/contacts/common/util/AccountsListAdapter.java b/src/com/android/contacts/common/util/AccountsListAdapter.java new file mode 100644 index 00000000..84435df8 --- /dev/null +++ b/src/com/android/contacts/common/util/AccountsListAdapter.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2010 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.contacts.common.util; + +import android.content.Context; +import android.text.TextUtils.TruncateAt; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.contacts.common.R; +import com.android.contacts.common.model.AccountTypeManager; +import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.AccountWithDataSet; + +import java.util.ArrayList; +import java.util.List; + +/** + * List-Adapter for Account selection + */ +public final class AccountsListAdapter extends BaseAdapter { + private final LayoutInflater mInflater; + private final List<AccountWithDataSet> mAccounts; + private final AccountTypeManager mAccountTypes; + private final Context mContext; + + /** + * Filters that affect the list of accounts that is displayed by this adapter. + */ + public enum AccountListFilter { + ALL_ACCOUNTS, // All read-only and writable accounts + ACCOUNTS_CONTACT_WRITABLE, // Only where the account type is contact writable + ACCOUNTS_GROUP_WRITABLE // Only accounts where the account type is group writable + } + + public AccountsListAdapter(Context context, AccountListFilter accountListFilter) { + this(context, accountListFilter, null); + } + + /** + * @param currentAccount the Account currently selected by the user, which should come + * first in the list. Can be null. + */ + public AccountsListAdapter(Context context, AccountListFilter accountListFilter, + AccountWithDataSet currentAccount) { + mContext = context; + mAccountTypes = AccountTypeManager.getInstance(context); + mAccounts = getAccounts(accountListFilter); + if (currentAccount != null + && !mAccounts.isEmpty() + && !mAccounts.get(0).equals(currentAccount) + && mAccounts.remove(currentAccount)) { + mAccounts.add(0, currentAccount); + } + mInflater = LayoutInflater.from(context); + } + + private List<AccountWithDataSet> getAccounts(AccountListFilter accountListFilter) { + if (accountListFilter == AccountListFilter.ACCOUNTS_GROUP_WRITABLE) { + return new ArrayList<AccountWithDataSet>(mAccountTypes.getGroupWritableAccounts()); + } + return new ArrayList<AccountWithDataSet>(mAccountTypes.getAccounts( + accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE)); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final View resultView = convertView != null ? convertView + : mInflater.inflate(R.layout.account_selector_list_item, parent, false); + + final TextView text1 = (TextView) resultView.findViewById(android.R.id.text1); + final TextView text2 = (TextView) resultView.findViewById(android.R.id.text2); + final ImageView icon = (ImageView) resultView.findViewById(android.R.id.icon); + + final AccountWithDataSet account = mAccounts.get(position); + final AccountType accountType = mAccountTypes.getAccountType(account.type, account.dataSet); + + text1.setText(accountType.getDisplayLabel(mContext)); + + // For email addresses, we don't want to truncate at end, which might cut off the domain + // name. + text2.setText(account.name); + text2.setEllipsize(TruncateAt.MIDDLE); + + icon.setImageDrawable(accountType.getDisplayIcon(mContext)); + + return resultView; + } + + @Override + public int getCount() { + return mAccounts.size(); + } + + @Override + public AccountWithDataSet getItem(int position) { + return mAccounts.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } +} + |