1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.messaging.ui.attachmentchooser;
17 
18 import android.app.Fragment;
19 import android.content.Context;
20 import android.graphics.Rect;
21 import android.net.Uri;
22 import android.os.Bundle;
23 import androidx.appcompat.app.ActionBar;
24 import android.view.LayoutInflater;
25 import android.view.Menu;
26 import android.view.MenuInflater;
27 import android.view.MenuItem;
28 import android.view.View;
29 import android.view.ViewGroup;
30 import android.widget.ArrayAdapter;
31 
32 import com.android.messaging.R;
33 import com.android.messaging.datamodel.DataModel;
34 import com.android.messaging.datamodel.MessagingContentProvider;
35 import com.android.messaging.datamodel.binding.Binding;
36 import com.android.messaging.datamodel.binding.BindingBase;
37 import com.android.messaging.datamodel.data.DraftMessageData;
38 import com.android.messaging.datamodel.data.DraftMessageData.DraftMessageDataListener;
39 import com.android.messaging.datamodel.data.MessagePartData;
40 import com.android.messaging.ui.BugleActionBarActivity;
41 import com.android.messaging.ui.UIIntents;
42 import com.android.messaging.ui.attachmentchooser.AttachmentGridView.AttachmentGridHost;
43 import com.google.common.annotations.VisibleForTesting;
44 
45 import java.util.ArrayList;
46 import java.util.List;
47 
48 public class AttachmentChooserFragment extends Fragment implements DraftMessageDataListener,
49         AttachmentGridHost {
50     public interface AttachmentChooserFragmentHost {
onConfirmSelection()51         void onConfirmSelection();
52     }
53 
54     private AttachmentGridView mAttachmentGridView;
55     private AttachmentGridAdapter mAdapter;
56     private AttachmentChooserFragmentHost mHost;
57 
58     @VisibleForTesting
59     Binding<DraftMessageData> mBinding = BindingBase.createBinding(this);
60 
61     @Override
onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)62     public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
63             final Bundle savedInstanceState) {
64         final View view = inflater.inflate(R.layout.attachment_chooser_fragment, container, false);
65         mAttachmentGridView = (AttachmentGridView) view.findViewById(R.id.grid);
66         mAdapter = new AttachmentGridAdapter(getActivity());
67         mAttachmentGridView.setAdapter(mAdapter);
68         mAttachmentGridView.setHost(this);
69         setHasOptionsMenu(true);
70         return view;
71     }
72 
73     @Override
onDestroy()74     public void onDestroy() {
75         super.onDestroy();
76         mBinding.unbind();
77     }
78 
79     @Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)80     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
81         super.onCreateOptionsMenu(menu, inflater);
82         inflater.inflate(R.menu.attachment_chooser_menu, menu);
83     }
84 
85     @Override
onOptionsItemSelected(MenuItem item)86     public boolean onOptionsItemSelected(MenuItem item) {
87         switch (item.getItemId()) {
88             case R.id.action_confirm_selection:
89                 confirmSelection();
90                 return true;
91 
92             default:
93                 return super.onOptionsItemSelected(item);
94         }
95     }
96 
97     @VisibleForTesting
confirmSelection()98     void confirmSelection() {
99         if (mBinding.isBound()) {
100             mBinding.getData().removeExistingAttachments(
101                     mAttachmentGridView.getUnselectedAttachments());
102             mBinding.getData().saveToStorage(mBinding);
103             mHost.onConfirmSelection();
104         }
105     }
106 
setConversationId(final String conversationId)107     public void setConversationId(final String conversationId) {
108         mBinding.bind(DataModel.get().createDraftMessageData(conversationId));
109         mBinding.getData().addListener(this);
110         mBinding.getData().loadFromStorage(mBinding, null, false);
111     }
112 
setHost(final AttachmentChooserFragmentHost host)113     public void setHost(final AttachmentChooserFragmentHost host) {
114         mHost = host;
115     }
116 
117     @Override
onDraftChanged(final DraftMessageData data, final int changeFlags)118     public void onDraftChanged(final DraftMessageData data, final int changeFlags) {
119         mBinding.ensureBound(data);
120         if ((changeFlags & DraftMessageData.ATTACHMENTS_CHANGED) ==
121                 DraftMessageData.ATTACHMENTS_CHANGED) {
122             mAdapter.onAttachmentsLoaded(data.getReadOnlyAttachments());
123         }
124     }
125 
126     @Override
onDraftAttachmentLimitReached(final DraftMessageData data)127     public void onDraftAttachmentLimitReached(final DraftMessageData data) {
128         // Do nothing since the user is in the process of unselecting attachments.
129     }
130 
131     @Override
onDraftAttachmentLoadFailed()132     public void onDraftAttachmentLoadFailed() {
133         // Do nothing since the user is in the process of unselecting attachments.
134     }
135 
136     @Override
displayPhoto(final Rect viewRect, final Uri photoUri)137     public void displayPhoto(final Rect viewRect, final Uri photoUri) {
138         final Uri imagesUri = MessagingContentProvider.buildDraftImagesUri(
139                 mBinding.getData().getConversationId());
140         UIIntents.get().launchFullScreenPhotoViewer(
141                 getActivity(), photoUri, viewRect, imagesUri);
142     }
143 
144     @Override
updateSelectionCount(int count)145     public void updateSelectionCount(int count) {
146         if (getActivity() instanceof BugleActionBarActivity) {
147             final ActionBar actionBar = ((BugleActionBarActivity) getActivity())
148                     .getSupportActionBar();
149             if (actionBar != null) {
150                 actionBar.setTitle(getResources().getString(
151                         R.string.attachment_chooser_selection, count));
152             }
153         }
154     }
155 
156     class AttachmentGridAdapter extends ArrayAdapter<MessagePartData> {
AttachmentGridAdapter(final Context context)157         public AttachmentGridAdapter(final Context context) {
158             super(context, R.layout.attachment_grid_item_view, new ArrayList<MessagePartData>());
159         }
160 
onAttachmentsLoaded(final List<MessagePartData> attachments)161         public void onAttachmentsLoaded(final List<MessagePartData> attachments) {
162             clear();
163             addAll(attachments);
164             notifyDataSetChanged();
165         }
166 
167         @Override
getView(final int position, final View convertView, final ViewGroup parent)168         public View getView(final int position, final View convertView, final ViewGroup parent) {
169             AttachmentGridItemView itemView;
170             final MessagePartData item = getItem(position);
171             if (convertView != null && convertView instanceof AttachmentGridItemView) {
172                 itemView = (AttachmentGridItemView) convertView;
173             } else {
174                 final LayoutInflater inflater = (LayoutInflater) getContext()
175                         .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
176                 itemView = (AttachmentGridItemView) inflater.inflate(
177                         R.layout.attachment_grid_item_view, parent, false);
178             }
179             itemView.bind(item, mAttachmentGridView);
180             return itemView;
181         }
182     }
183 }
184