blob: 360d2ca3d4dc73cf33fc82116c5a94117e01d0e6 [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 */
alisionf76de3b2013-04-16 15:35:22 -040032package com.savoirfairelinux.sflphone.fragments;
33
alisionf76de3b2013-04-16 15:35:22 -040034import java.util.ArrayList;
Alexandre Savarda04c5202012-09-18 17:19:53 -040035
alision55c36cb2013-06-14 14:57:38 -040036import android.animation.LayoutTransition;
Emeric Vigier1f1ced32012-11-02 16:56:32 -040037import android.app.Activity;
alisiond295ec22013-05-17 10:12:13 -040038import android.app.Fragment;
Alexandre Savard6668cf82012-09-19 10:59:21 -040039import android.app.LoaderManager;
Alexandre Savard6668cf82012-09-19 10:59:21 -040040import android.content.Loader;
Alexandre Savard6668cf82012-09-19 10:59:21 -040041import android.net.Uri;
Alexandre Savarda04c5202012-09-18 17:19:53 -040042import android.os.Bundle;
Alexandre Savard6668cf82012-09-19 10:59:21 -040043import android.provider.ContactsContract.Contacts;
Alexandre Savard6668cf82012-09-19 10:59:21 -040044import android.text.TextUtils;
alisionf76de3b2013-04-16 15:35:22 -040045import android.util.Log;
alisiond295ec22013-05-17 10:12:13 -040046import android.view.DragEvent;
Alexandre Savarda04c5202012-09-18 17:19:53 -040047import android.view.LayoutInflater;
Alexandre Savard6668cf82012-09-19 10:59:21 -040048import android.view.Menu;
Alexandre Savard6668cf82012-09-19 10:59:21 -040049import android.view.MenuInflater;
Alexandre Savarda04c5202012-09-18 17:19:53 -040050import android.view.View;
alisiond295ec22013-05-17 10:12:13 -040051import android.view.View.DragShadowBuilder;
alision84813a12013-05-27 17:40:39 -040052import android.view.View.OnClickListener;
alisiond295ec22013-05-17 10:12:13 -040053import android.view.View.OnDragListener;
Alexandre Savarda04c5202012-09-18 17:19:53 -040054import android.view.ViewGroup;
Alexandre Savard31433992012-09-20 15:19:49 -040055import android.widget.AdapterView;
alisiond295ec22013-05-17 10:12:13 -040056import android.widget.AdapterView.OnItemClickListener;
Alexandre Savard31433992012-09-20 15:19:49 -040057import android.widget.AdapterView.OnItemLongClickListener;
alision84813a12013-05-27 17:40:39 -040058import android.widget.ImageButton;
alision55c36cb2013-06-14 14:57:38 -040059import android.widget.LinearLayout;
alisionf76de3b2013-04-16 15:35:22 -040060import android.widget.ListView;
alision84813a12013-05-27 17:40:39 -040061import android.widget.RelativeLayout;
alisionf76de3b2013-04-16 15:35:22 -040062import android.widget.SearchView;
Alexandre Savard6668cf82012-09-19 10:59:21 -040063import android.widget.SearchView.OnQueryTextListener;
Alexandre Savarda04c5202012-09-18 17:19:53 -040064
65import com.savoirfairelinux.sflphone.R;
alisiond295ec22013-05-17 10:12:13 -040066import com.savoirfairelinux.sflphone.adapters.ContactsAdapter;
67import com.savoirfairelinux.sflphone.adapters.StarredContactsAdapter;
alisiond295ec22013-05-17 10:12:13 -040068import com.savoirfairelinux.sflphone.loaders.ContactsLoader;
alision2ec64f92013-06-17 17:28:58 -040069import com.savoirfairelinux.sflphone.loaders.LoaderConstants;
alisiond295ec22013-05-17 10:12:13 -040070import com.savoirfairelinux.sflphone.model.CallContact;
alision84813a12013-05-27 17:40:39 -040071import com.savoirfairelinux.sflphone.service.ISipService;
alisiond295ec22013-05-17 10:12:13 -040072import com.savoirfairelinux.sflphone.views.TACGridView;
Alexandre Savarda04c5202012-09-18 17:19:53 -040073
alisiond295ec22013-05-17 10:12:13 -040074public class ContactListFragment extends Fragment implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Bundle> {
alision84813a12013-05-27 17:40:39 -040075 private static final String TAG = "ContactListFragment";
alisiond8c83882013-05-17 17:00:42 -040076 ContactsAdapter mListAdapter;
77 StarredContactsAdapter mGridAdapter;
alisiond295ec22013-05-17 10:12:13 -040078
alisiond8c83882013-05-17 17:00:42 -040079 String mCurFilter;
Alexandre Savard6668cf82012-09-19 10:59:21 -040080
alisiond8c83882013-05-17 17:00:42 -040081 @Override
82 public void onCreate(Bundle savedInBundle) {
83 super.onCreate(savedInBundle);
84 mListAdapter = new ContactsAdapter(getActivity());
85 mGridAdapter = new StarredContactsAdapter(getActivity());
86 }
Alexandre Savarda04c5202012-09-18 17:19:53 -040087
alision84813a12013-05-27 17:40:39 -040088 private Callbacks mCallbacks = sDummyCallbacks;
89 /**
90 * A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
91 */
92 private static Callbacks sDummyCallbacks = new Callbacks() {
93 @Override
94 public void onContactSelected(CallContact c) {
95 }
96
97 @Override
98 public ISipService getService() {
99 Log.i(TAG, "Dummy");
100 return null;
101 }
102
alisiond45da712013-05-30 09:18:49 -0400103 @Override
104 public void onContactDragged() {
105 }
106
alision58356b72013-06-03 17:13:36 -0400107 @Override
108 public void openDrawer() {
109 }
110
alision84813a12013-05-27 17:40:39 -0400111 };
112
113 public interface Callbacks {
114 void onContactSelected(CallContact c);
115
116 public ISipService getService();
117
alisiond45da712013-05-30 09:18:49 -0400118 void onContactDragged();
119
alision58356b72013-06-03 17:13:36 -0400120 void openDrawer();
121
alision84813a12013-05-27 17:40:39 -0400122 }
123
alisiond8c83882013-05-17 17:00:42 -0400124 @Override
125 public void onAttach(Activity activity) {
126 super.onAttach(activity);
alision84813a12013-05-27 17:40:39 -0400127 if (!(activity instanceof Callbacks)) {
128 throw new IllegalStateException("Activity must implement fragment's callbacks.");
129 }
130
131 mCallbacks = (Callbacks) activity;
alisiond8c83882013-05-17 17:00:42 -0400132 }
alision55c36cb2013-06-14 14:57:38 -0400133
alisionfde875f2013-05-28 17:01:54 -0400134 @Override
135 public void onDetach() {
136 super.onDetach();
137 mCallbacks = sDummyCallbacks;
138 }
Emeric Vigier1f1ced32012-11-02 16:56:32 -0400139
alisiond8c83882013-05-17 17:00:42 -0400140 @Override
141 public void onActivityCreated(Bundle savedInstanceState) {
142 super.onActivityCreated(savedInstanceState);
Alexandre Savarda04c5202012-09-18 17:19:53 -0400143
alisiond8c83882013-05-17 17:00:42 -0400144 // In order to onCreateOptionsMenu be called
145 setHasOptionsMenu(true);
alision2ec64f92013-06-17 17:28:58 -0400146 getLoaderManager().initLoader(LoaderConstants.CONTACT_LOADER, null, this);
Alexandre Savarda04c5202012-09-18 17:19:53 -0400147
alisiond8c83882013-05-17 17:00:42 -0400148 }
Alexandre Savard23240c12012-09-19 18:23:44 -0400149
alisiond8c83882013-05-17 17:00:42 -0400150 ListView list;
Alexandre Savard31433992012-09-20 15:19:49 -0400151
alisiond8c83882013-05-17 17:00:42 -0400152 private OnItemLongClickListener mItemLongClickListener = new OnItemLongClickListener() {
153 @Override
154 public boolean onItemLongClick(AdapterView<?> av, View view, int pos, long id) {
155 DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view.findViewById(R.id.photo));
156 view.startDrag(null, shadowBuilder, view, 0);
alision55c36cb2013-06-14 14:57:38 -0400157 // view.setVisibility(View.INVISIBLE);
alisiond45da712013-05-30 09:18:49 -0400158 mCallbacks.onContactDragged();
alision55c36cb2013-06-14 14:57:38 -0400159// ((SearchView) mHandle.findViewById(R.id.contact_search_text)).setIconified(true);
alisiond8c83882013-05-17 17:00:42 -0400160 return true;
161 }
alisiond295ec22013-05-17 10:12:13 -0400162
alisiond8c83882013-05-17 17:00:42 -0400163 };
alisiond295ec22013-05-17 10:12:13 -0400164
alisiond8c83882013-05-17 17:00:42 -0400165 @Override
166 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
167 View inflatedView = inflater.inflate(R.layout.frag_contact_list, container, false);
168 list = (ListView) inflatedView.findViewById(R.id.contacts_list);
alisiond295ec22013-05-17 10:12:13 -0400169
alisiond8c83882013-05-17 17:00:42 -0400170 list.setOnDragListener(dragListener);
171 list.setOnItemClickListener(new OnItemClickListener() {
alisiond295ec22013-05-17 10:12:13 -0400172
alisiond8c83882013-05-17 17:00:42 -0400173 @Override
174 public void onItemClick(AdapterView<?> arg0, View v, int pos, long arg3) {
alisionf4571d92013-07-04 17:11:35 -0400175 mCallbacks.onContactSelected(mListAdapter.getItem(pos-1));
alision55c36cb2013-06-14 14:57:38 -0400176// ((SearchView) mHandle.findViewById(R.id.contact_search_text)).setIconified(true);
177
alisiond8c83882013-05-17 17:00:42 -0400178 }
179 });
180 list.setOnItemLongClickListener(mItemLongClickListener);
alisiond295ec22013-05-17 10:12:13 -0400181
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);
188 grid.setExpanded(true);
alision55c36cb2013-06-14 14:57:38 -0400189
alisiond8c83882013-05-17 17:00:42 -0400190 grid.setOnDragListener(dragListener);
191 grid.setOnItemClickListener(new OnItemClickListener() {
Alexandre Savard0014d232012-09-24 10:31:23 -0400192
alisiond8c83882013-05-17 17:00:42 -0400193 @Override
194 public void onItemClick(AdapterView<?> arg0, View v, int pos, long arg3) {
alision55c36cb2013-06-14 14:57:38 -0400195 // launchCallActivity(mGridAdapter.getItem(pos));
alision84813a12013-05-27 17:40:39 -0400196 mCallbacks.onContactSelected(mGridAdapter.getItem(pos));
alision55c36cb2013-06-14 14:57:38 -0400197// ((SearchView) mHandle.findViewById(R.id.contact_search_text)).setIconified(true);
alisiond8c83882013-05-17 17:00:42 -0400198 }
199 });
200 grid.setOnItemLongClickListener(mItemLongClickListener);
alisiond295ec22013-05-17 10:12:13 -0400201
alisiond8c83882013-05-17 17:00:42 -0400202 return inflatedView;
203 }
alisiond295ec22013-05-17 10:12:13 -0400204
alisiond8c83882013-05-17 17:00:42 -0400205 OnDragListener dragListener = new OnDragListener() {
Alexandre Savard0014d232012-09-24 10:31:23 -0400206
alisiond8c83882013-05-17 17:00:42 -0400207 @Override
208 public boolean onDrag(View v, DragEvent event) {
209 switch (event.getAction()) {
210 case DragEvent.ACTION_DRAG_STARTED:
211 // Do nothing
212 break;
213 case DragEvent.ACTION_DRAG_ENTERED:
214 break;
215 case DragEvent.ACTION_DRAG_EXITED:
alision55c36cb2013-06-14 14:57:38 -0400216 // v.setBackgroundDrawable(null);
alisiond8c83882013-05-17 17:00:42 -0400217 break;
218 case DragEvent.ACTION_DROP:
alisiond8c83882013-05-17 17:00:42 -0400219 break;
220 case DragEvent.ACTION_DRAG_ENDED:
221 View view1 = (View) event.getLocalState();
222 view1.setVisibility(View.VISIBLE);
223 default:
224 break;
225 }
226 return true;
227 }
Alexandre Savarda04c5202012-09-18 17:19:53 -0400228
alisiond8c83882013-05-17 17:00:42 -0400229 };
Alexandre Savarda04c5202012-09-18 17:19:53 -0400230
alisiond8c83882013-05-17 17:00:42 -0400231 @Override
232 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
233 // Place an action bar item for searching
alision55c36cb2013-06-14 14:57:38 -0400234 // inflater.inflate(R.menu.contact_list_menu, menu);
235 // MenuItem item = menu.findItem(R.id.menu_search);
236 // SearchView sv = new SearchView(getActivity());
237 // sv.setOnQueryTextListener(this);
238 // item.setActionView(sv);
alisiond8c83882013-05-17 17:00:42 -0400239 }
alisiond295ec22013-05-17 10:12:13 -0400240
alisiond8c83882013-05-17 17:00:42 -0400241 @Override
242 public boolean onQueryTextChange(String newText) {
alision55c36cb2013-06-14 14:57:38 -0400243
alisiond8c83882013-05-17 17:00:42 -0400244 // Called when the action bar search text has changed. Update
245 // the search filter, and restart the loader to do a new query
246 // with this filter.
247 String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
248 // Don't do anything if the filter hasn't actually changed.
249 // Prefents restarting the loader when restoring state.
250 if (mCurFilter == null && newFilter == null) {
251 return true;
252 }
253 if (mCurFilter != null && mCurFilter.equals(newFilter)) {
254 return true;
255 }
256 mCurFilter = newFilter;
alision2ec64f92013-06-17 17:28:58 -0400257 Bundle b = new Bundle();
258 b.putString("filter", mCurFilter);
259 getLoaderManager().restartLoader(LoaderConstants.CONTACT_LOADER, b, this);
alisiond8c83882013-05-17 17:00:42 -0400260 return true;
261 }
alisiond295ec22013-05-17 10:12:13 -0400262
alisiond8c83882013-05-17 17:00:42 -0400263 @Override
264 public boolean onQueryTextSubmit(String query) {
265 // Return false to let the SearchView perform the default action
266 return false;
267 }
alisiond295ec22013-05-17 10:12:13 -0400268
alisiond8c83882013-05-17 17:00:42 -0400269 @Override
270 public Loader<Bundle> onCreateLoader(int id, Bundle args) {
271 Uri baseUri;
alision17052d42013-04-22 10:39:38 -0400272
alision2ec64f92013-06-17 17:28:58 -0400273 if (args != null) {
274 baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(args.getString("filter")));
alisiond8c83882013-05-17 17:00:42 -0400275 } else {
276 baseUri = Contacts.CONTENT_URI;
277 }
278 ContactsLoader l = new ContactsLoader(getActivity(), baseUri);
279 l.forceLoad();
280 return l;
281 }
Alexandre Savard6668cf82012-09-19 10:59:21 -0400282
alisiond8c83882013-05-17 17:00:42 -0400283 @Override
284 public void onLoadFinished(Loader<Bundle> loader, Bundle data) {
Alexandre Savard6668cf82012-09-19 10:59:21 -0400285
alisiond8c83882013-05-17 17:00:42 -0400286 mListAdapter.removeAll();
287 mGridAdapter.removeAll();
288 ArrayList<CallContact> tmp = data.getParcelableArrayList("Contacts");
289 ArrayList<CallContact> tmp2 = data.getParcelableArrayList("Starred");
Alexandre Savard6668cf82012-09-19 10:59:21 -0400290
alisiond8c83882013-05-17 17:00:42 -0400291 Log.w(TAG, "Contact stareed " + tmp2.size());
292 mListAdapter.addAll(tmp);
293 mGridAdapter.addAll(tmp2);
Alexandre Savard6668cf82012-09-19 10:59:21 -0400294
alisiond8c83882013-05-17 17:00:42 -0400295 }
Alexandre Savard6668cf82012-09-19 10:59:21 -0400296
alisiond8c83882013-05-17 17:00:42 -0400297 @Override
298 public void onLoaderReset(Loader<Bundle> loader) {
299 // Thi is called when the last Cursor provided to onLoadFinished
300 // mListAdapter.swapCursor(null);
301 }
alision84813a12013-05-27 17:40:39 -0400302
303 public void setHandleView(RelativeLayout handle) {
alision84813a12013-05-27 17:40:39 -0400304
alision55c36cb2013-06-14 14:57:38 -0400305 ((ImageButton)handle.findViewById(R.id.contact_search_button)).setOnClickListener(new OnClickListener() {
alision58356b72013-06-03 17:13:36 -0400306
307 @Override
308 public void onClick(View v) {
alision907bde72013-06-20 14:40:37 -0400309 Log.i(TAG,"onClick");
alision55c36cb2013-06-14 14:57:38 -0400310 SearchView search = new SearchView(getActivity());
311 //Get the ID for the search bar LinearLayout
312 int searchBarId = search.getContext().getResources().getIdentifier("android:id/search_bar", null, null);
313 //Get the search bar Linearlayout
314 LinearLayout searchBar = (LinearLayout) search.findViewById(searchBarId);
315 searchBar.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
316 //Give the Linearlayout a transition animation.
317 searchBar.setLayoutTransition(new LayoutTransition());
318 search.setOnQueryTextListener(ContactListFragment.this);
319 search.setIconified(false);
320 getActivity().getActionBar().setDisplayShowCustomEnabled(true);
321 getActivity().getActionBar().setCustomView(search);
alision58356b72013-06-03 17:13:36 -0400322 mCallbacks.openDrawer();
323
324 }
325 });
alision84813a12013-05-27 17:40:39 -0400326
alision84813a12013-05-27 17:40:39 -0400327
alision55c36cb2013-06-14 14:57:38 -0400328
alision84813a12013-05-27 17:40:39 -0400329 }
alision55c36cb2013-06-14 14:57:38 -0400330
Alexandre Savarda04c5202012-09-18 17:19:53 -0400331}