blob: 3b04166c4244a75c589bef9e30eac0994faf4ca3 [file] [log] [blame]
Alexandre Savarda04c5202012-09-18 17:19:53 -04001/*
alisiond295ec22013-05-17 10:12:13 -04002 * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
Alexandre Savarda04c5202012-09-18 17:19:53 -04003 *
Alexandre Savard23240c12012-09-19 18:23:44 -04004 * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
alisiond295ec22013-05-17 10:12:13 -04005 * Alexandre Lision <alexandre.lision@savoirfairelinux.com>
Alexandre Savarda04c5202012-09-18 17:19:53 -04006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * Additional permission under GNU GPL version 3 section 7:
22 *
23 * If you modify this program, or any covered work, by linking or
24 * combining it with the OpenSSL project's OpenSSL library (or a
25 * modified version of that library), containing parts covered by the
26 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
27 * grants you additional permission to convey the resulting work.
28 * Corresponding Source for a non-source form of such a combination
29 * shall include the source code for the parts of OpenSSL used as well
30 * as that of the covered work.
31 */
Alexandre Lision064e1e02013-10-01 16:18:42 -040032package org.sflphone.fragments;
alisionf76de3b2013-04-16 15:35:22 -040033
alisionf76de3b2013-04-16 15:35:22 -040034import java.util.ArrayList;
Alexandre Savarda04c5202012-09-18 17:19:53 -040035
Alexandre Lision064e1e02013-10-01 16:18:42 -040036import org.sflphone.R;
37import org.sflphone.adapters.ContactsAdapter;
38import org.sflphone.adapters.StarredContactsAdapter;
39import org.sflphone.loaders.ContactsLoader;
40import org.sflphone.loaders.LoaderConstants;
41import org.sflphone.model.CallContact;
42import org.sflphone.service.ISipService;
43import org.sflphone.views.TACGridView;
44
alision55c36cb2013-06-14 14:57:38 -040045import android.animation.LayoutTransition;
Emeric Vigier1f1ced32012-11-02 16:56:32 -040046import android.app.Activity;
alisiond295ec22013-05-17 10:12:13 -040047import android.app.Fragment;
Alexandre Savard6668cf82012-09-19 10:59:21 -040048import android.app.LoaderManager;
Alexandre Savard6668cf82012-09-19 10:59:21 -040049import android.content.Loader;
Alexandre Savard6668cf82012-09-19 10:59:21 -040050import android.net.Uri;
Alexandre Savarda04c5202012-09-18 17:19:53 -040051import android.os.Bundle;
Alexandre Savard6668cf82012-09-19 10:59:21 -040052import android.provider.ContactsContract.Contacts;
alisionf76de3b2013-04-16 15:35:22 -040053import android.util.Log;
alisiond295ec22013-05-17 10:12:13 -040054import android.view.DragEvent;
Alexandre Savarda04c5202012-09-18 17:19:53 -040055import android.view.LayoutInflater;
56import android.view.View;
alisiond295ec22013-05-17 10:12:13 -040057import android.view.View.DragShadowBuilder;
alision84813a12013-05-27 17:40:39 -040058import android.view.View.OnClickListener;
alisiond295ec22013-05-17 10:12:13 -040059import android.view.View.OnDragListener;
Alexandre Savarda04c5202012-09-18 17:19:53 -040060import android.view.ViewGroup;
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -040061import android.widget.AbsListView;
62import android.widget.AbsListView.OnScrollListener;
Alexandre Savard31433992012-09-20 15:19:49 -040063import android.widget.AdapterView;
alisiond295ec22013-05-17 10:12:13 -040064import android.widget.AdapterView.OnItemClickListener;
Alexandre Savard31433992012-09-20 15:19:49 -040065import android.widget.AdapterView.OnItemLongClickListener;
alision84813a12013-05-27 17:40:39 -040066import android.widget.ImageButton;
alision55c36cb2013-06-14 14:57:38 -040067import android.widget.LinearLayout;
alisionf76de3b2013-04-16 15:35:22 -040068import android.widget.ListView;
alision84813a12013-05-27 17:40:39 -040069import android.widget.RelativeLayout;
alisionf76de3b2013-04-16 15:35:22 -040070import android.widget.SearchView;
Alexandre Savard6668cf82012-09-19 10:59:21 -040071import android.widget.SearchView.OnQueryTextListener;
Alexandre Savarda04c5202012-09-18 17:19:53 -040072
alisiond295ec22013-05-17 10:12:13 -040073public class ContactListFragment extends Fragment implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Bundle> {
alision84813a12013-05-27 17:40:39 -040074 private static final String TAG = "ContactListFragment";
alisiond8c83882013-05-17 17:00:42 -040075 ContactsAdapter mListAdapter;
76 StarredContactsAdapter mGridAdapter;
alisiond295ec22013-05-17 10:12:13 -040077
alisiond8c83882013-05-17 17:00:42 -040078 String mCurFilter;
Alexandre Savard6668cf82012-09-19 10:59:21 -040079
alisiond8c83882013-05-17 17:00:42 -040080 @Override
81 public void onCreate(Bundle savedInBundle) {
82 super.onCreate(savedInBundle);
83 mListAdapter = new ContactsAdapter(getActivity());
84 mGridAdapter = new StarredContactsAdapter(getActivity());
85 }
Alexandre Savarda04c5202012-09-18 17:19:53 -040086
alision84813a12013-05-27 17:40:39 -040087 private Callbacks mCallbacks = sDummyCallbacks;
88 /**
89 * A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
90 */
91 private static Callbacks sDummyCallbacks = new Callbacks() {
92 @Override
93 public void onContactSelected(CallContact c) {
94 }
95
96 @Override
97 public ISipService getService() {
98 Log.i(TAG, "Dummy");
99 return null;
100 }
101
alisiond45da712013-05-30 09:18:49 -0400102 @Override
103 public void onContactDragged() {
104 }
105
alision58356b72013-06-03 17:13:36 -0400106 @Override
107 public void openDrawer() {
108 }
109
alision84813a12013-05-27 17:40:39 -0400110 };
111
112 public interface Callbacks {
113 void onContactSelected(CallContact c);
114
115 public ISipService getService();
116
alisiond45da712013-05-30 09:18:49 -0400117 void onContactDragged();
118
alision58356b72013-06-03 17:13:36 -0400119 void openDrawer();
120
alision84813a12013-05-27 17:40:39 -0400121 }
122
alisiond8c83882013-05-17 17:00:42 -0400123 @Override
124 public void onAttach(Activity activity) {
125 super.onAttach(activity);
alision84813a12013-05-27 17:40:39 -0400126 if (!(activity instanceof Callbacks)) {
127 throw new IllegalStateException("Activity must implement fragment's callbacks.");
128 }
129
130 mCallbacks = (Callbacks) activity;
alisiond8c83882013-05-17 17:00:42 -0400131 }
alision55c36cb2013-06-14 14:57:38 -0400132
alisionfde875f2013-05-28 17:01:54 -0400133 @Override
134 public void onDetach() {
135 super.onDetach();
136 mCallbacks = sDummyCallbacks;
137 }
Emeric Vigier1f1ced32012-11-02 16:56:32 -0400138
alisiond8c83882013-05-17 17:00:42 -0400139 @Override
140 public void onActivityCreated(Bundle savedInstanceState) {
141 super.onActivityCreated(savedInstanceState);
Alexandre Savarda04c5202012-09-18 17:19:53 -0400142
alisiond8c83882013-05-17 17:00:42 -0400143 // In order to onCreateOptionsMenu be called
144 setHasOptionsMenu(true);
alision2ec64f92013-06-17 17:28:58 -0400145 getLoaderManager().initLoader(LoaderConstants.CONTACT_LOADER, null, this);
Alexandre Savarda04c5202012-09-18 17:19:53 -0400146
alisiond8c83882013-05-17 17:00:42 -0400147 }
Alexandre Savard23240c12012-09-19 18:23:44 -0400148
alisiond8c83882013-05-17 17:00:42 -0400149 ListView list;
Alexandre Savard31433992012-09-20 15:19:49 -0400150
alisiond8c83882013-05-17 17:00:42 -0400151 private OnItemLongClickListener mItemLongClickListener = new OnItemLongClickListener() {
152 @Override
153 public boolean onItemLongClick(AdapterView<?> av, View view, int pos, long id) {
154 DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view.findViewById(R.id.photo));
155 view.startDrag(null, shadowBuilder, view, 0);
alision55c36cb2013-06-14 14:57:38 -0400156 // view.setVisibility(View.INVISIBLE);
alisiond45da712013-05-30 09:18:49 -0400157 mCallbacks.onContactDragged();
Alexandre Lisione2839d52013-10-01 09:37:37 -0400158 // ((SearchView) mHandle.findViewById(R.id.contact_search_text)).setIconified(true);
alisiond8c83882013-05-17 17:00:42 -0400159 return true;
160 }
alisiond295ec22013-05-17 10:12:13 -0400161
alisiond8c83882013-05-17 17:00:42 -0400162 };
alisiond295ec22013-05-17 10:12:13 -0400163
alisiond8c83882013-05-17 17:00:42 -0400164 @Override
165 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
166 View inflatedView = inflater.inflate(R.layout.frag_contact_list, container, false);
167 list = (ListView) inflatedView.findViewById(R.id.contacts_list);
alisiond295ec22013-05-17 10:12:13 -0400168
alisiond8c83882013-05-17 17:00:42 -0400169 list.setOnDragListener(dragListener);
170 list.setOnItemClickListener(new OnItemClickListener() {
alisiond295ec22013-05-17 10:12:13 -0400171
alisiond8c83882013-05-17 17:00:42 -0400172 @Override
173 public void onItemClick(AdapterView<?> arg0, View v, int pos, long arg3) {
Alexandre Lisione2839d52013-10-01 09:37:37 -0400174 mCallbacks.onContactSelected(mListAdapter.getItem(pos - 1));
175 // ((SearchView) mHandle.findViewById(R.id.contact_search_text)).setIconified(true);
alision55c36cb2013-06-14 14:57:38 -0400176
alisiond8c83882013-05-17 17:00:42 -0400177 }
178 });
179 list.setOnItemLongClickListener(mItemLongClickListener);
alisiond295ec22013-05-17 10:12:13 -0400180
Alexandre Lision573045c2013-09-11 17:20:25 -0400181 list.setEmptyView(inflatedView.findViewById(R.id.empty_list_contact));
alisiond8c83882013-05-17 17:00:42 -0400182 View header = inflater.inflate(R.layout.frag_contact_list_header, null);
183 list.addHeaderView(header, null, false);
184 TACGridView grid = (TACGridView) header.findViewById(R.id.favorites_grid);
Alexandre Savardaef9d802012-09-20 17:31:32 -0400185
alisiond8c83882013-05-17 17:00:42 -0400186 list.setAdapter(mListAdapter);
187 grid.setAdapter(mGridAdapter);
Alexandre Lisione2839d52013-10-01 09:37:37 -0400188
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -0400189 list.setOnScrollListener(new OnScrollListener() {
Alexandre Lisione2839d52013-10-01 09:37:37 -0400190
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -0400191 @Override
192 public void onScrollStateChanged(AbsListView view, int scrollState) {
193 // TODO Stub de la méthode généré automatiquement
Alexandre Lisione2839d52013-10-01 09:37:37 -0400194
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -0400195 }
Alexandre Lisione2839d52013-10-01 09:37:37 -0400196
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -0400197 @Override
198 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
Alexandre Lisione2839d52013-10-01 09:37:37 -0400199 if (visibleItemCount > 0 && firstVisibleItem == 0 && view.getChildAt(0).getTop() == 0) {
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -0400200 // ListView scrolled at top
Alexandre Lisione2839d52013-10-01 09:37:37 -0400201
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -0400202 }
Alexandre Lisione2839d52013-10-01 09:37:37 -0400203
Alexandre Lisionf7ae8bf2013-09-27 16:33:26 -0400204 }
205 });
alisiond8c83882013-05-17 17:00:42 -0400206 grid.setExpanded(true);
alision55c36cb2013-06-14 14:57:38 -0400207
alisiond8c83882013-05-17 17:00:42 -0400208 grid.setOnDragListener(dragListener);
209 grid.setOnItemClickListener(new OnItemClickListener() {
Alexandre Savard0014d232012-09-24 10:31:23 -0400210
alisiond8c83882013-05-17 17:00:42 -0400211 @Override
212 public void onItemClick(AdapterView<?> arg0, View v, int pos, long arg3) {
alision55c36cb2013-06-14 14:57:38 -0400213 // launchCallActivity(mGridAdapter.getItem(pos));
alision84813a12013-05-27 17:40:39 -0400214 mCallbacks.onContactSelected(mGridAdapter.getItem(pos));
Alexandre Lisione2839d52013-10-01 09:37:37 -0400215 // ((SearchView) mHandle.findViewById(R.id.contact_search_text)).setIconified(true);
alisiond8c83882013-05-17 17:00:42 -0400216 }
217 });
218 grid.setOnItemLongClickListener(mItemLongClickListener);
alisiond295ec22013-05-17 10:12:13 -0400219
alisiond8c83882013-05-17 17:00:42 -0400220 return inflatedView;
221 }
alisiond295ec22013-05-17 10:12:13 -0400222
alisiond8c83882013-05-17 17:00:42 -0400223 OnDragListener dragListener = new OnDragListener() {
Alexandre Savard0014d232012-09-24 10:31:23 -0400224
alisiond8c83882013-05-17 17:00:42 -0400225 @Override
226 public boolean onDrag(View v, DragEvent event) {
227 switch (event.getAction()) {
228 case DragEvent.ACTION_DRAG_STARTED:
229 // Do nothing
230 break;
231 case DragEvent.ACTION_DRAG_ENTERED:
232 break;
233 case DragEvent.ACTION_DRAG_EXITED:
alision55c36cb2013-06-14 14:57:38 -0400234 // v.setBackgroundDrawable(null);
alisiond8c83882013-05-17 17:00:42 -0400235 break;
236 case DragEvent.ACTION_DROP:
alisiond8c83882013-05-17 17:00:42 -0400237 break;
238 case DragEvent.ACTION_DRAG_ENDED:
239 View view1 = (View) event.getLocalState();
240 view1.setVisibility(View.VISIBLE);
241 default:
242 break;
243 }
244 return true;
245 }
Alexandre Savarda04c5202012-09-18 17:19:53 -0400246
alisiond8c83882013-05-17 17:00:42 -0400247 };
Alexandre Savarda04c5202012-09-18 17:19:53 -0400248
alisiond8c83882013-05-17 17:00:42 -0400249 @Override
250 public boolean onQueryTextChange(String newText) {
alision55c36cb2013-06-14 14:57:38 -0400251
alisiond8c83882013-05-17 17:00:42 -0400252 // Called when the action bar search text has changed. Update
253 // the search filter, and restart the loader to do a new query
254 // with this filter.
Alexandre Lisione2839d52013-10-01 09:37:37 -0400255 // String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
alisiond8c83882013-05-17 17:00:42 -0400256 // Don't do anything if the filter hasn't actually changed.
257 // Prefents restarting the loader when restoring state.
Alexandre Lisione2839d52013-10-01 09:37:37 -0400258 // if (mCurFilter == null && newFilter == null) {
259 // return true;
260 // }
261 // if (mCurFilter != null && mCurFilter.equals(newText)) {
262 // return true;
263 // }
264 if (newText.isEmpty()) {
Alexandre Lision22db86b2013-09-24 13:33:28 -0400265 getLoaderManager().restartLoader(LoaderConstants.CONTACT_LOADER, null, this);
alisiond8c83882013-05-17 17:00:42 -0400266 return true;
267 }
Alexandre Lision22db86b2013-09-24 13:33:28 -0400268 mCurFilter = newText;
alision2ec64f92013-06-17 17:28:58 -0400269 Bundle b = new Bundle();
270 b.putString("filter", mCurFilter);
271 getLoaderManager().restartLoader(LoaderConstants.CONTACT_LOADER, b, this);
alisiond8c83882013-05-17 17:00:42 -0400272 return true;
273 }
alisiond295ec22013-05-17 10:12:13 -0400274
alisiond8c83882013-05-17 17:00:42 -0400275 @Override
276 public boolean onQueryTextSubmit(String query) {
277 // Return false to let the SearchView perform the default action
278 return false;
279 }
alisiond295ec22013-05-17 10:12:13 -0400280
alisiond8c83882013-05-17 17:00:42 -0400281 @Override
282 public Loader<Bundle> onCreateLoader(int id, Bundle args) {
283 Uri baseUri;
alision17052d42013-04-22 10:39:38 -0400284
alision2ec64f92013-06-17 17:28:58 -0400285 if (args != null) {
286 baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(args.getString("filter")));
alisiond8c83882013-05-17 17:00:42 -0400287 } else {
288 baseUri = Contacts.CONTENT_URI;
289 }
290 ContactsLoader l = new ContactsLoader(getActivity(), baseUri);
291 l.forceLoad();
292 return l;
293 }
Alexandre Savard6668cf82012-09-19 10:59:21 -0400294
alisiond8c83882013-05-17 17:00:42 -0400295 @Override
296 public void onLoadFinished(Loader<Bundle> loader, Bundle data) {
Alexandre Savard6668cf82012-09-19 10:59:21 -0400297
alisiond8c83882013-05-17 17:00:42 -0400298 mListAdapter.removeAll();
299 mGridAdapter.removeAll();
300 ArrayList<CallContact> tmp = data.getParcelableArrayList("Contacts");
301 ArrayList<CallContact> tmp2 = data.getParcelableArrayList("Starred");
Alexandre Savard6668cf82012-09-19 10:59:21 -0400302
alisiond8c83882013-05-17 17:00:42 -0400303 Log.w(TAG, "Contact stareed " + tmp2.size());
304 mListAdapter.addAll(tmp);
305 mGridAdapter.addAll(tmp2);
Alexandre Savard6668cf82012-09-19 10:59:21 -0400306
alisiond8c83882013-05-17 17:00:42 -0400307 }
Alexandre Savard6668cf82012-09-19 10:59:21 -0400308
alisiond8c83882013-05-17 17:00:42 -0400309 @Override
310 public void onLoaderReset(Loader<Bundle> loader) {
311 // Thi is called when the last Cursor provided to onLoadFinished
312 // mListAdapter.swapCursor(null);
313 }
alision84813a12013-05-27 17:40:39 -0400314
315 public void setHandleView(RelativeLayout handle) {
Alexandre Lisione2839d52013-10-01 09:37:37 -0400316
317 ((ImageButton) handle.findViewById(R.id.contact_search_button)).setOnClickListener(new OnClickListener() {
318
alision58356b72013-06-03 17:13:36 -0400319 @Override
320 public void onClick(View v) {
Alexandre Lisione2839d52013-10-01 09:37:37 -0400321
alision55c36cb2013-06-14 14:57:38 -0400322 SearchView search = new SearchView(getActivity());
Alexandre Lisione2839d52013-10-01 09:37:37 -0400323 // Get the ID for the search bar LinearLayout
alision55c36cb2013-06-14 14:57:38 -0400324 int searchBarId = search.getContext().getResources().getIdentifier("android:id/search_bar", null, null);
Alexandre Lisione2839d52013-10-01 09:37:37 -0400325 // Get the search bar Linearlayout
alision55c36cb2013-06-14 14:57:38 -0400326 LinearLayout searchBar = (LinearLayout) search.findViewById(searchBarId);
Alexandre Lisione2839d52013-10-01 09:37:37 -0400327 searchBar.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
328 LinearLayout.LayoutParams.WRAP_CONTENT));
329 // Give the Linearlayout a transition animation.
alision55c36cb2013-06-14 14:57:38 -0400330 searchBar.setLayoutTransition(new LayoutTransition());
331 search.setOnQueryTextListener(ContactListFragment.this);
332 search.setIconified(false);
333 getActivity().getActionBar().setDisplayShowCustomEnabled(true);
334 getActivity().getActionBar().setCustomView(search);
alision58356b72013-06-03 17:13:36 -0400335 mCallbacks.openDrawer();
Alexandre Lisione2839d52013-10-01 09:37:37 -0400336
alision58356b72013-06-03 17:13:36 -0400337 }
338 });
alision55c36cb2013-06-14 14:57:38 -0400339
alision84813a12013-05-27 17:40:39 -0400340 }
alision55c36cb2013-06-14 14:57:38 -0400341
Alexandre Savarda04c5202012-09-18 17:19:53 -0400342}