blob: d073f68d4151f8bae03cd9bcc625f023eaac5f77 [file] [log] [blame]
/*
* Copyright (C) 2015 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.editor;
import com.android.contacts.ContactSaveService;
import com.android.contacts.R;
import com.android.contacts.activities.CompactContactEditorActivity;
import com.android.contacts.activities.ContactEditorActivity;
import com.android.contacts.activities.ContactEditorBaseActivity;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.RawContactDelta;
import com.android.contacts.common.model.RawContactDeltaList;
import com.android.contacts.common.model.ValuesDelta;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.detail.PhotoSelectionHandler;
import com.android.contacts.util.ContactPhotoUtils;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.util.ArrayList;
/**
* Contact editor with only the most important fields displayed initially.
*/
public class CompactContactEditorFragment extends ContactEditorBaseFragment implements
CompactRawContactsEditorView.Listener, CompactPhotoEditorView.Listener {
private static final String KEY_PHOTO_RAW_CONTACT_ID = "photo_raw_contact_id";
private static final String KEY_UPDATED_PHOTOS = "updated_photos";
private long mPhotoRawContactId;
private Bundle mUpdatedPhotos = new Bundle();
@Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
if (savedState != null) {
mPhotoRawContactId = savedState.getLong(KEY_PHOTO_RAW_CONTACT_ID);
mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
setHasOptionsMenu(true);
final View view = inflater.inflate(
R.layout.compact_contact_editor_fragment, container, false);
mContent = (LinearLayout) view.findViewById(R.id.raw_contacts_editor_view);
return view;
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putLong(KEY_PHOTO_RAW_CONTACT_ID, mPhotoRawContactId);
outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos);
super.onSaveInstanceState(outState);
}
@Override
public void onStop() {
super.onStop();
// If anything was left unsaved, save it now
if (!getActivity().isChangingConfigurations() && mStatus == Status.EDITING) {
save(SaveMode.RELOAD);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
return revert();
}
return super.onOptionsItemSelected(item);
}
@Override
protected void bindEditors() {
if (!isReadyToBindEditors()) {
return;
}
// Add input fields for the loaded Contact
final CompactRawContactsEditorView editorView = getContent();
editorView.setListener(this);
editorView.setState(mState, getMaterialPalette(), mViewIdGenerator, mPhotoId,
mHasNewContact, mIsUserProfile, mAccountWithDataSet);
// Set up the photo widget
editorView.setPhotoListener(this);
mPhotoRawContactId = editorView.getPhotoRawContactId();
// If there is an updated full resolution photo apply it now, this will be the case if
// the user selects or takes a new photo, then rotates the device.
final Uri uri = (Uri) mUpdatedPhotos.get(String.valueOf(mPhotoRawContactId));
if (uri != null) {
editorView.setFullSizePhoto(uri);
}
// The editor is ready now so make it visible
editorView.setEnabled(isEnabled());
editorView.setVisibility(View.VISIBLE);
// Refresh the ActionBar as the visibility of the join command
// Activity can be null if we have been detached from the Activity.
invalidateOptionsMenu();
}
private boolean isReadyToBindEditors() {
if (mState.isEmpty()) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "No data to bind editors");
}
return false;
}
if (mIsEdit && !mExistingContactDataReady) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Existing contact data is not ready to bind editors.");
}
return false;
}
if (mHasNewContact && !mNewContactDataReady) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "New contact data is not ready to bind editors.");
}
return false;
}
return true;
}
@Override
protected View getAggregationAnchorView(long rawContactId) {
return getContent().getAggregationAnchorView();
}
@Override
protected void setGroupMetaData() {
if (mGroupMetaData != null) {
getContent().setGroupMetaData(mGroupMetaData);
}
}
@Override
protected boolean doSaveAction(int saveMode) {
final Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState,
SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(),
((Activity) mContext).getClass(),
CompactContactEditorActivity.ACTION_SAVE_COMPLETED, mUpdatedPhotos);
mContext.startService(intent);
return true;
}
@Override
protected void joinAggregate(final long contactId) {
final Intent intent = ContactSaveService.createJoinContactsIntent(
mContext, mContactIdForJoin, contactId, CompactContactEditorActivity.class,
CompactContactEditorActivity.ACTION_JOIN_COMPLETED);
mContext.startService(intent);
}
public void removePhoto() {
getContent().removePhoto();
mUpdatedPhotos.remove(String.valueOf(mPhotoRawContactId));
}
public void updatePhoto(Uri uri) throws FileNotFoundException {
final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(getActivity(), uri);
if (bitmap == null || bitmap.getHeight() <= 0 || bitmap.getWidth() <= 0) {
Toast.makeText(getContext(), R.string.contactPhotoSavedErrorToast,
Toast.LENGTH_SHORT).show();
return;
}
mUpdatedPhotos.putParcelable(String.valueOf(mPhotoRawContactId), uri);
getContent().updatePhoto(uri);
}
public void setPrimaryPhoto(CompactPhotoSelectionFragment.Photo photo) {
getContent().setPrimaryPhoto(photo);
}
@Override
public void onNameFieldChanged(long rawContactId, ValuesDelta valuesDelta) {
final Activity activity = getActivity();
if (activity == null || activity.isFinishing()) {
return;
}
if (!mIsUserProfile) {
acquireAggregationSuggestions(activity, rawContactId, valuesDelta);
}
}
@Override
public void onRebindEditorsForNewContact(RawContactDelta oldState,
AccountWithDataSet oldAccount, AccountWithDataSet newAccount) {
mNewContactAccountChanged = true;
mAccountWithDataSet = newAccount;
rebindEditorsForNewContact(oldState, oldAccount, newAccount);
}
@Override
public void onBindEditorsFailed() {
final Activity activity = getActivity();
if (activity != null && !activity.isFinishing()) {
Toast.makeText(activity, R.string.compact_editor_failed_to_load,
Toast.LENGTH_SHORT).show();
activity.setResult(Activity.RESULT_CANCELED);
activity.finish();
}
}
@Override
public void onEditorsBound() {
getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupsLoaderListener);
}
@Override
public void onPhotoEditorViewClicked() {
if (isMultiAccountContact()) {
final ArrayList<CompactPhotoSelectionFragment.Photo> photos = getContent().getPhotos();
if (!photos.isEmpty()) {
// For aggregate contacts, the user may select a new super primary photo from among
// the (non-default) raw contact photos, or source a new photo from the ActionBar
getEditorActivity().selectPhoto(photos, getPhotoMode());
return;
}
}
// For contacts composed of a single writable raw contact, or no raw contacts have photos,
// clicking the photo view simply opens the source photo dialog
getEditorActivity().changePhoto(getPhotoMode());
}
@Override
public void onRawContactSelected(Uri uri, long rawContactId, boolean isReadOnly) {
final Activity activity = getActivity();
if (activity != null && !activity.isFinishing()) {
final Intent intent = EditorIntents.createEditContactIntentForRawContact(
activity, uri, rawContactId, isReadOnly);
activity.startActivity(intent);
}
}
private int getPhotoMode() {
if (getContent().isWritablePhotoSet()) {
return isMultiAccountContact()
? PhotoActionPopup.Modes.MULTIPLE_WRITE_ABLE_PHOTOS
: PhotoActionPopup.Modes.WRITE_ABLE_PHOTO;
}
return PhotoActionPopup.Modes.NO_PHOTO;
}
private CompactContactEditorActivity getEditorActivity() {
return (CompactContactEditorActivity) getActivity();
}
private CompactRawContactsEditorView getContent() {
return (CompactRawContactsEditorView) mContent;
}
}