* #24533 New Contact List, with data model
* #23415 general refactoring
diff --git a/src/com/savoirfairelinux/sflphone/account/AudioHandler.java b/src/com/savoirfairelinux/sflphone/account/AudioHandler.java
new file mode 100644
index 0000000..589d7d8
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/account/AudioHandler.java
@@ -0,0 +1,28 @@
+package com.savoirfairelinux.sflphone.account;
+
+import java.util.ArrayList;
+
+import android.util.Log;
+
+import com.savoirfairelinux.sflphone.service.IntVect;
+
+public class AudioHandler {
+
+ private static final String TAG = AudioHandler.class.getSimpleName();
+
+ public static ArrayList<Integer> convertSwigToNative(IntVect swigmap) {
+
+ ArrayList<Integer> nativemap = new ArrayList<Integer>();
+
+ Log.w(TAG, "size codecs list " + swigmap.size());
+
+ for (int i = 0; i < swigmap.size(); ++i) {
+
+ Integer t = swigmap.get(i);
+ nativemap.add(t);
+ }
+
+ return nativemap;
+ }
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/account/HistoryHandler.java b/src/com/savoirfairelinux/sflphone/account/HistoryHandler.java
index d10571d..ae5dfd3 100644
--- a/src/com/savoirfairelinux/sflphone/account/HistoryHandler.java
+++ b/src/com/savoirfairelinux/sflphone/account/HistoryHandler.java
@@ -5,24 +5,12 @@
import android.util.Log;
-import com.savoirfairelinux.sflphone.R;
import com.savoirfairelinux.sflphone.service.ServiceConstants;
-import com.savoirfairelinux.sflphone.service.StringMap;
import com.savoirfairelinux.sflphone.service.VectMap;
public class HistoryHandler {
private static final String TAG = HistoryHandler.class.getSimpleName();
- public static class PreferenceEntry {
- public String mKey;
- public int mLabelId;
-
- public PreferenceEntry(String key, int labelId) {
- mKey = key;
- mLabelId = labelId;
- }
- }
-
public static ArrayList<HashMap<String, String>> convertSwigToNative(VectMap swigmap) {
diff --git a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
index 76eeed3..264be71 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
@@ -121,7 +121,7 @@
private void queueAccount(String id, AccountView row) {
// This ImageView might have been used for other images, so we clear
// the queue of old tasks before starting.
- accountQueue.Clean(row);
+// accountQueue.Clean(row);
AccountRef p = new AccountRef(id, row);
synchronized (accountQueue.accountRefsStack) {
@@ -151,15 +151,15 @@
private Stack<AccountRef> accountRefsStack = new Stack<AccountRef>();
// removes all instances of this account
- public void Clean(AccountView view) {
-
- for (int i = 0; i < accountRefsStack.size();) {
- if (accountRefsStack.get(i).row == view)
- accountRefsStack.remove(i);
- else
- ++i;
- }
- }
+// public void Clean(AccountView view) {
+//
+// for (int i = 0; i < accountRefsStack.size();) {
+// if (accountRefsStack.get(i).row == view)
+// accountRefsStack.remove(i);
+// else
+// ++i;
+// }
+// }
}
private class AccountQueueManager implements Runnable {
diff --git a/src/com/savoirfairelinux/sflphone/adapters/ContactPictureLoader.java b/src/com/savoirfairelinux/sflphone/adapters/ContactPictureLoader.java
new file mode 100644
index 0000000..7f64aa8
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/adapters/ContactPictureLoader.java
@@ -0,0 +1,83 @@
+package com.savoirfairelinux.sflphone.adapters;
+
+import java.io.InputStream;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.widget.ImageView;
+
+import com.savoirfairelinux.sflphone.R;
+
+public class ContactPictureLoader implements Runnable {
+ private ImageView view;
+ private long cid;
+ private ContentResolver cr;
+ private final String TAG = ContactPictureLoader.class.getSimpleName();
+
+ public ContactPictureLoader(Context context, ImageView element, long contact_id) {
+ cid = contact_id;
+ cr = context.getContentResolver();
+ view = element;
+ }
+
+ public Bitmap loadContactPhoto(ContentResolver cr, long id) {
+ Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
+ InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
+ if (input == null) {
+ return null;
+ }
+ return BitmapFactory.decodeStream(input);
+ }
+
+ @Override
+ public void run() {
+ Bitmap photo_bmp = loadContactPhoto(cr, cid);
+
+ if (photo_bmp == null) {
+ photo_bmp = BitmapFactory.decodeResource(view.getResources(), R.drawable.ic_contact_picture);
+
+ }
+
+
+ int w = photo_bmp.getWidth(), h = photo_bmp.getHeight();
+
+ final Bitmap externalBMP = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+
+ int radius = externalBMP.getWidth() / 2;
+ Path path = new Path();
+
+ path.addCircle(radius, radius, radius, Path.Direction.CW);
+ Paint mPaintPath = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mPaintPath.setStyle(Paint.Style.FILL);
+ mPaintPath.setAntiAlias(true);
+ Bitmap circle = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ Canvas circle_drawer = new Canvas(circle);
+ circle_drawer.drawOval(new RectF(0, 0, w, h), mPaintPath);
+ mPaintPath.setFilterBitmap(false);
+
+ Canvas internalCanvas = new Canvas(externalBMP);
+ internalCanvas.drawBitmap(photo_bmp, 0, 0, mPaintPath);
+ mPaintPath.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
+ internalCanvas.drawBitmap(circle, 0, 0, mPaintPath);
+
+ view.post(new Runnable() {
+ @Override
+ public void run() {
+ view.setImageBitmap(externalBMP);
+ view.invalidate();
+ }
+ });
+ }
+}
diff --git a/src/com/savoirfairelinux/sflphone/adapters/ContactsAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/ContactsAdapter.java
new file mode 100644
index 0000000..2f4f9f8
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/adapters/ContactsAdapter.java
@@ -0,0 +1,85 @@
+package com.savoirfairelinux.sflphone.adapters;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.provider.ContactsContract;
+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.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.model.CallContact;
+
+public class ContactsAdapter extends BaseAdapter {
+
+ private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
+ private ArrayList<CallContact> dataset;
+ Context mContext;
+
+ private static final String TAG = ContactsAdapter.class.getSimpleName();
+
+ public ContactsAdapter(Context context) {
+ super();
+ mContext = context;
+ dataset = new ArrayList<CallContact>();
+ }
+
+ public void removeAll() {
+ dataset.clear();
+ notifyDataSetChanged();
+ }
+
+ public void addAll(ArrayList<CallContact> arrayList) {
+ dataset.addAll(arrayList);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return dataset.size();
+ }
+
+ @Override
+ public CallContact getItem(int index) {
+ return dataset.get(index);
+ }
+
+ @Override
+ public long getItemId(int index) {
+ return dataset.get(index).getId();
+ }
+
+ @Override
+ public View getView(int pos, View convView, ViewGroup parent) {
+
+ View v = convView;
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ if (v == null) {
+ v = inflater.inflate(R.layout.item_contact, null);
+ }
+
+ CallContact item = dataset.get(pos);
+
+ ((TextView) v.findViewById(R.id.display_name)).setText(item.getmDisplayName());
+ ImageView photo_view = (ImageView) v.findViewById(R.id.photo);
+
+ infos_fetcher.execute(new ContactPictureLoader(mContext, photo_view, item.getId()));
+
+ return v;
+ }
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/adapters/StarredContactsAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/StarredContactsAdapter.java
new file mode 100644
index 0000000..fcb1df5
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/adapters/StarredContactsAdapter.java
@@ -0,0 +1,76 @@
+package com.savoirfairelinux.sflphone.adapters;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import android.content.Context;
+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.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.model.CallContact;
+
+public class StarredContactsAdapter extends BaseAdapter {
+
+ private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
+ private ArrayList<CallContact> dataset;
+ Context mContext;
+
+ private static final String TAG = ContactsAdapter.class.getSimpleName();
+
+ public StarredContactsAdapter(Context context) {
+ super();
+ mContext = context;
+ dataset = new ArrayList<CallContact>();
+ }
+
+ public void removeAll() {
+ dataset.clear();
+ notifyDataSetChanged();
+ }
+
+ public void addAll(ArrayList<CallContact> arrayList) {
+ dataset.addAll(arrayList);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return dataset.size();
+ }
+
+ @Override
+ public Object getItem(int index) {
+ return dataset.get(index);
+ }
+
+ @Override
+ public long getItemId(int index) {
+ return dataset.get(index).getId();
+ }
+
+ @Override
+ public View getView(int pos, View convView, ViewGroup parent) {
+
+ View v = convView;
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ if (v == null) {
+ v = inflater.inflate(R.layout.item_contact_starred, null);
+ }
+
+ CallContact item = dataset.get(pos);
+
+ ((TextView) v.findViewById(R.id.display_name)).setText(item.getmDisplayName());
+ ImageView photo_view = (ImageView) v.findViewById(R.id.photo);
+
+ infos_fetcher.execute(new ContactPictureLoader(mContext, photo_view, item.getId()));
+
+ return v;
+ }
+}
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/client/CallActivity.java b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
index e5feab3..5473a8e 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
@@ -93,13 +93,13 @@
Bundle b = getIntent().getExtras();
// Parcelable value = b.getParcelable("CallInfo");
- SipCall.CallInfo info = b.getParcelable("CallInfo");
- Log.i(TAG, "Starting activity for call " + info.mCallID);
- mCall = new SipCall(info);
-
- Intent intent = new Intent(this, SipService.class);
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- setCallStateDisplay(mCall.getCallStateString());
+// SipCall.CallInfo info = b.getParcelable("CallInfo");
+// Log.i(TAG, "Starting activity for call " + info.mCallID);
+// mCall = new SipCall(info);
+//
+// Intent intent = new Intent(this, SipService.class);
+// bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+// setCallStateDisplay(mCall.getCallStateString());
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter(CallManagerCallBack.NEW_CALL_CREATED));
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter(CallManagerCallBack.CALL_STATE_CHANGED));
diff --git a/src/com/savoirfairelinux/sflphone/client/CallElementView.java b/src/com/savoirfairelinux/sflphone/client/CallElementView.java
deleted file mode 100644
index bb605c3..0000000
--- a/src/com/savoirfairelinux/sflphone/client/CallElementView.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
- *
- * Author: Adrien Beraud <adrien.beraud@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Additional permission under GNU GPL version 3 section 7:
- *
- * If you modify this program, or any covered work, by linking or
- * combining it with the OpenSSL project's OpenSSL library (or a
- * modified version of that library), containing parts covered by the
- * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- * grants you additional permission to convey the resulting work.
- * Corresponding Source for a non-source form of such a combination
- * shall include the source code for the parts of OpenSSL used as well
- * as that of the covered work.
- */
-package com.savoirfairelinux.sflphone.client;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.widget.FrameLayout;
-
-public class CallElementView extends FrameLayout
-{
- private ViewGroup contactCard = null;
- private ViewGroup callCard = null;
-
- public CallElementView(Context context, AttributeSet attrs)
- {
- super(context, attrs);
- }
-
- public CallElementView(Context context, AttributeSet attrs, int defStyle)
- {
- super(context, attrs, defStyle);
- }
-
- @Override
- protected void onAttachedToWindow()
- {
- // Layouts may be inflated or we may use fragments.
- // contactCard = (ViewGroup) findViewById(R.id.contactview);
- // callCard = (ViewGroup) findViewById(R.id.callview);
- // callCard.setVisibility(View.GONE);
- }
-
- private Interpolator accelerator = new AccelerateInterpolator();
- private Interpolator decelerator = new DecelerateInterpolator();
-
- // from Android API Demo "ListFlipper"
- private void flipit()
- {
- if (contactCard == null || callCard == null)
- return;
-
- final View visibleList;
- final View invisibleList;
- if (contactCard.getVisibility() == View.GONE) {
- visibleList = callCard;
- invisibleList = contactCard;
- } else {
- invisibleList = callCard;
- visibleList = contactCard;
- }
- ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibleList, "rotationY", 0f, 90f);
- visToInvis.setDuration(500);
- visToInvis.setInterpolator(accelerator);
- final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibleList, "rotationY", -90f, 0f);
- invisToVis.setDuration(500);
- invisToVis.setInterpolator(decelerator);
- visToInvis.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator anim)
- {
- visibleList.setVisibility(View.GONE);
- invisToVis.start();
- invisibleList.setVisibility(View.VISIBLE);
- }
- });
- visToInvis.start();
- }
-
-}
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index dd1a746..1be9909 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -30,8 +30,6 @@
*/
package com.savoirfairelinux.sflphone.client;
-import java.io.ObjectInputStream.GetField;
-
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
@@ -55,6 +53,7 @@
import com.savoirfairelinux.sflphone.R;
import com.savoirfairelinux.sflphone.fragments.CallElementListFragment;
import com.savoirfairelinux.sflphone.fragments.ContactListFragment;
+import com.savoirfairelinux.sflphone.fragments.DialingFragment;
import com.savoirfairelinux.sflphone.fragments.HistoryFragment;
import com.savoirfairelinux.sflphone.model.SipCall;
import com.savoirfairelinux.sflphone.service.ISipClient;
@@ -66,7 +65,7 @@
static final String TAG = "SFLPhoneHome";
private static final int REQUEST_CODE_PREFERENCES = 1;
ImageButton buttonCall, buttonHangup;
- private ContactListFragment mContactListFragment = null;
+ private ContactListFragment mDialingFragment = null;
private CallElementListFragment mCallElementList = null;
private HistoryFragment mHistorySectionFragment = null;
private boolean mBound = false;
@@ -103,6 +102,9 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ String libraryPath = getApplicationInfo().dataDir + "/lib";
+ Log.i(TAG, libraryPath);
// Bind to LocalService
if (!mBound) {
@@ -121,7 +123,7 @@
if (savedInstanceState != null) {
Log.w(TAG, "Activity restarted, recreating PagerAdapter...");
/* getFragment (Bundle bundle, String key) */
- mContactListFragment = (ContactListFragment) getFragmentManager().getFragment(savedInstanceState,
+ mDialingFragment = (ContactListFragment) getFragmentManager().getFragment(savedInstanceState,
mSectionsPagerAdapter.getClassName(ACTION_BAR_TAB_CONTACT));
mCallElementList = (CallElementListFragment) getFragmentManager().getFragment(savedInstanceState,
mSectionsPagerAdapter.getClassName(ACTION_BAR_TAB_CALL));
@@ -129,9 +131,9 @@
mSectionsPagerAdapter.getClassName(ACTION_BAR_TAB_HISTORY));
}
- if (mContactListFragment == null) {
- mContactListFragment = new ContactListFragment();
- Log.w(TAG, "Recreated mContactListFragment=" + mContactListFragment);
+ if (mDialingFragment == null) {
+ mDialingFragment = new ContactListFragment();
+ Log.w(TAG, "Recreated mContactListFragment=" + mDialingFragment);
}
if (mCallElementList == null) {
mCallElementList = new CallElementListFragment();
@@ -379,8 +381,8 @@
switch (i) {
case 0:
- mContactListFragment = new ContactListFragment();
- fragment = mContactListFragment;
+ mDialingFragment = new ContactListFragment();
+ fragment = mDialingFragment;
Log.w(TAG, "getItem() ContactListFragment=" + fragment);
break;
case 1:
@@ -411,7 +413,7 @@
switch (i) {
case 0:
- fragment = mContactListFragment;
+ fragment = mDialingFragment;
break;
case 1:
fragment = mCallElementList;
diff --git a/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java b/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java
index 3adf846..c3e3e54 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java
@@ -292,6 +292,10 @@
HashMap<String, String> accountDetails = null;
try {
accountDetails = (HashMap<String, String>) service.getAccountDetails(accountID);
+ ArrayList<Integer> tmp = (ArrayList<Integer>) service.getAudioCodecList(accountID);
+ for(Integer i : tmp){
+ Log.w(TAG,"Codec : "+i);
+ }
if (accountDetails.containsKey("TLS.negotiationTimeoutSec"))
Log.i(TAG, "localinterface existe");
diff --git a/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
index 3d44b13..766e60e 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ * Alexandre Lision <alexandre.lision@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,240 +31,198 @@
*/
package com.savoirfairelinux.sflphone.fragments;
-import java.io.InputStream;
import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ListFragment;
+import android.app.Fragment;
import android.app.LoaderManager;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.CursorLoader;
-import android.content.DialogInterface;
+import android.content.Intent;
import android.content.Loader;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.BaseColumns;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.Contacts;
import android.support.v4.view.MenuItemCompat;
import android.text.TextUtils;
import android.util.Log;
+import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.View.DragShadowBuilder;
+import android.view.View.OnDragListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.CursorAdapter;
-import android.widget.ImageView;
+import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
-import android.widget.TextView;
import com.savoirfairelinux.sflphone.R;
-import com.savoirfairelinux.sflphone.client.SFLPhoneHomeActivity;
-import com.savoirfairelinux.sflphone.client.SFLphoneApplication;
+import com.savoirfairelinux.sflphone.adapters.ContactsAdapter;
+import com.savoirfairelinux.sflphone.adapters.StarredContactsAdapter;
+import com.savoirfairelinux.sflphone.client.CallActivity;
+import com.savoirfairelinux.sflphone.loaders.ContactsLoader;
+import com.savoirfairelinux.sflphone.model.CallContact;
import com.savoirfairelinux.sflphone.model.SipCall;
import com.savoirfairelinux.sflphone.service.ISipService;
+import com.savoirfairelinux.sflphone.views.TACGridView;
-public class ContactListFragment extends ListFragment implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {
+public class ContactListFragment extends Fragment implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Bundle> {
final String TAG = "ContactListFragment";
- ContactElementAdapter mAdapter;
- Activity mContext;
+ ContactsAdapter mListAdapter;
+ StarredContactsAdapter mGridAdapter;
+
String mCurFilter;
- private SFLPhoneHomeActivity sflphoneHome;
- private SFLphoneApplication sflphoneApplication;
private ISipService service;
- // These are the Contacts rows that we will retrieve.
- static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Contacts.PHOTO_ID, Contacts.LOOKUP_KEY };
- static final String[] CONTACTS_PHONES_PROJECTION = new String[] { Phone.NUMBER, Phone.TYPE };
- static final String[] CONTACTS_SIP_PROJECTION = new String[] { SipAddress.SIP_ADDRESS, SipAddress.TYPE };
+ public static final int CONTACT_LOADER = 555;
+
+ @Override
+ public void onCreate(Bundle savedInBundle) {
+ super.onCreate(savedInBundle);
+ mListAdapter = new ContactsAdapter(getActivity());
+ mGridAdapter = new StarredContactsAdapter(getActivity());
+ }
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
- sflphoneHome = (SFLPhoneHomeActivity) activity;
- sflphoneApplication = (SFLphoneApplication) sflphoneHome.getApplication();
- service = sflphoneApplication.getSipService();
}
- public static class InfosLoader implements Runnable {
- private ImageView view;
- private long cid;
- private ContentResolver cr;
- private static final String TAG = InfosLoader.class.getSimpleName();
-
- public InfosLoader(Context context, ImageView element, long contact_id) {
- cid = contact_id;
- cr = context.getContentResolver();
- view = element;
- }
-
- public static Bitmap loadContactPhoto(ContentResolver cr, long id) {
- Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
- InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
- if (input == null) {
- return null;
- }
- return BitmapFactory.decodeStream(input);
- }
-
- @Override
- public void run() {
- final Bitmap photo_bmp = loadContactPhoto(cr, cid);
-
- Cursor phones = cr.query(CommonDataKinds.Phone.CONTENT_URI, CONTACTS_PHONES_PROJECTION, CommonDataKinds.Phone.CONTACT_ID + " = ?",
- new String[] { Long.toString(cid) }, null);
-
- final List<String> numbers = new ArrayList<String>();
- while (phones.moveToNext()) {
- String number = phones.getString(phones.getColumnIndex(CommonDataKinds.Phone.NUMBER));
- // int type = phones.getInt(phones.getColumnIndex(CommonDataKinds.Phone.TYPE));
- numbers.add(number);
- }
- phones.close();
-
- final Bitmap bmp = photo_bmp;
- view.post(new Runnable() {
- @Override
- public void run() {
- view.setImageBitmap(bmp);
- }
- });
- }
- }
-
- public static class ContactElementAdapter extends CursorAdapter {
- private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
- private static final String TAG = ContactElementAdapter.class.getSimpleName();
- public ContactElementAdapter(Context context, Cursor c) {
- super(context, c, 0);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- LayoutInflater inflater = LayoutInflater.from(context);
- View v = inflater.inflate(R.layout.item_contact, parent, false);
- bindView(v, context, cursor);
- return v;
- }
-
- @Override
- public void bindView(final View view, Context context, Cursor cursor) {
- final long contact_id = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
- final String display_name = cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME));
- final long photo_id = cursor.getLong(cursor.getColumnIndex(Contacts.PHOTO_ID));
- Log.i(TAG,"photo_id "+photo_id);
-// final String photo_uri_thumb_string = cursor.getString(cursor.getColumnIndex(Contacts.PHOTO_THUMBNAIL_URI));
-
- TextView display_name_txt = (TextView) view.findViewById(R.id.display_name);
- display_name_txt.setText(display_name);
-
- ImageView photo_view = (ImageView) view.findViewById(R.id.photo);
- // photo_view.setVisibility(View.GONE);
-
- if (photo_id != 0) {
- infos_fetcher.execute(new InfosLoader(context, photo_view, contact_id));
- } else {
- photo_view.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_contact_picture));
- }
- }
- };
-
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mContext = getActivity();
// In order to onCreateOptionsMenu be called
setHasOptionsMenu(true);
+ getLoaderManager().initLoader(CONTACT_LOADER, null, this);
- mAdapter = new ContactElementAdapter(mContext, null);
- setListAdapter(mAdapter);
+ }
- getLoaderManager().initLoader(0, null, this);
+ ListView list;
- ListView lv = getListView();
- lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View inflatedView = inflater.inflate(R.layout.frag_contact_list, container, false);
+ list = (ListView) inflatedView.findViewById(R.id.contacts_list);
+
+ list.setOnDragListener(dragListener);
+
+ list.setOnItemClickListener(new OnItemClickListener() {
+
@Override
- public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
- Log.i(TAG, "On Long Click");
- final CharSequence[] items = { "Make Call", "Send Message", "Add to Conference" };
- final SipCall.CallInfo info = new SipCall.CallInfo();
- info.mDisplayName = (String) ((TextView) v.findViewById(R.id.display_name)).getText();
- info.mPhone = (String) ((TextView) v.findViewById(R.id.phones)).getText();
- // TODO getCallInstnace should be implemented in SipCallList
- // final SipCall call = SipCall.getCallInstance(info);
- final SipCall call = new SipCall(info);
- // FIXME
- service = sflphoneApplication.getSipService();
- AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
- builder.setTitle("Action to perform with " + call.mCallInfo.mDisplayName).setCancelable(true)
- .setItems(items, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- Log.i(TAG, "Selected " + items[item]);
- switch (item) {
- case 0:
-// call.placeCallUpdateUi();
- break;
- case 1:
- call.sendTextMessage();
- // Need to hangup this call immediately since no way to do it after this action
- call.notifyServiceHangup(service);
- break;
- case 2:
- call.addToConference();
- // Need to hangup this call immediately since no way to do it after this action
- call.notifyServiceHangup(service);
- break;
- default:
- break;
- }
- }
- });
- AlertDialog alert = builder.create();
- alert.show();
+ public void onItemClick(AdapterView<?> arg0, View view, int pos, long arg3) {
+
+ Log.i(TAG, "Launch Call Activity");
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("CallContact", mListAdapter.getItem(pos));
+ Intent intent = new Intent().setClass(getActivity(), CallActivity.class);
+ intent.putExtras(bundle);
+ getActivity().startActivity(intent);
+
+ }
+ });
+
+ list.setOnItemLongClickListener(new OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView<?> av, View view, int pos, long id) {
+ DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view.findViewById(R.id.photo));
+ view.startDrag(null, shadowBuilder, view, 0);
+ view.setVisibility(View.INVISIBLE);
+ // Log.i(TAG, "On Long Click");
+ // final CharSequence[] items = { "Make Call", "Send Message", "Add to Conference" };
+ // final SipCall.CallInfo info = new SipCall.CallInfo();
+ // info.mDisplayName = (String) ((TextView) v.findViewById(R.id.display_name)).getText();
+ // info.mPhone = (String) ((TextView) v.findViewById(R.id.phones)).getText();
+ // // TODO getCallInstnace should be implemented in SipCallList
+ // // final SipCall call = SipCall.getCallInstance(info);
+ // final SipCall call = new SipCall(info);
+ //
+ // AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ // builder.setTitle("Action to perform with " + call.mCallInfo.mDisplayName).setCancelable(true)
+ // .setItems(items, new DialogInterface.OnClickListener() {
+ // public void onClick(DialogInterface dialog, int item) {
+ // Log.i(TAG, "Selected " + items[item]);
+ // switch (item) {
+ // case 0:
+ // // call.placeCallUpdateUi();
+ // break;
+ // case 1:
+ // call.sendTextMessage();
+ // // Need to hangup this call immediately since no way to do it after this action
+ // call.notifyServiceHangup(service);
+ // break;
+ // case 2:
+ // call.addToConference();
+ // // Need to hangup this call immediately since no way to do it after this action
+ // call.notifyServiceHangup(service);
+ // break;
+ // default:
+ // break;
+ // }
+ // }
+ // });
+ // AlertDialog alert = builder.create();
+ // alert.show();
return true;
}
});
- lv.setOnItemSelectedListener(new OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- Log.i(TAG, "On Item Selected");
- }
+ View header = inflater.inflate(R.layout.frag_contact_list_header, null);
+ list.addHeaderView(header, null, false);
+ TACGridView grid = (TACGridView) header.findViewById(R.id.favorites_grid);
+
+ list.setAdapter(mListAdapter);
+ grid.setAdapter(mGridAdapter);
+ grid.setExpanded(true);
+ grid.setOnDragListener(dragListener);
+
+ grid.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
- public void onNothingSelected(AdapterView<?> parent) {
- Log.i(TAG, "On Nothing Selected");
+ public boolean onItemLongClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
+ DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view.findViewById(R.id.photo));
+ view.startDrag(null, shadowBuilder, view, 0);
+ view.setVisibility(View.INVISIBLE);
+ return true;
}
});
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View inflatedView = inflater.inflate(R.layout.frag_contact_list, container, false);
return inflatedView;
}
+ OnDragListener dragListener = new OnDragListener() {
+
+ @Override
+ public boolean onDrag(View v, DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ // Do nothing
+ break;
+ case DragEvent.ACTION_DRAG_ENTERED:
+ break;
+ case DragEvent.ACTION_DRAG_EXITED:
+ v.setBackgroundDrawable(null);
+ break;
+ case DragEvent.ACTION_DROP:
+ View view = (View) event.getLocalState();
+ break;
+ case DragEvent.ACTION_DRAG_ENDED:
+ View view1 = (View) event.getLocalState();
+ view1.setVisibility(View.VISIBLE);
+ default:
+ break;
+ }
+ return true;
+ }
+
+ };
+
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Place an action bar item for searching
@@ -277,25 +236,6 @@
}
@Override
- public void onListItemClick(ListView l, View v, int position, long id) {
- // Insert desired behavior here.
- SipCall.CallInfo callInfo = new SipCall.CallInfo();
- callInfo.mDisplayName = (String) ((TextView) v.findViewById(R.id.display_name)).getText();
- callInfo.mPhone = (String) ((TextView) v.findViewById(R.id.phones)).getText();
- Log.i(TAG, "Contact clicked: " + callInfo.mDisplayName + ", Phone number: " + callInfo.mPhone);
-
- // TODO This should be implemented in CallList
- // int nbCallBefore = SipCall.getNbCalls();
- // SipCall call = SipCall.getCallInstance(callInfo);
- // Log.i(TAG, "Number of calls " + SipCall.getNbCalls());
- // int nbCallAfter = SipCall.getNbCalls();
- SipCall call = new SipCall(callInfo);
-
- // if(nbCallAfter > nbCallBefore)
- // call.placeCall();
- }
-
- @Override
public boolean onQueryTextChange(String newText) {
// Called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
@@ -310,7 +250,7 @@
return true;
}
mCurFilter = newFilter;
- getLoaderManager().restartLoader(0, null, this);
+ getLoaderManager().restartLoader(CONTACT_LOADER, null, this);
return true;
}
@@ -321,7 +261,7 @@
}
@Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ public Loader<Bundle> onCreateLoader(int id, Bundle args) {
Uri baseUri;
if (mCurFilter != null) {
@@ -329,24 +269,28 @@
} else {
baseUri = Contacts.CONTENT_URI;
}
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + Contacts.DISPLAY_NAME
- + " != '' ))";
-
- return new CursorLoader(getActivity(), baseUri, CONTACTS_SUMMARY_PROJECTION, select, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
+ ContactsLoader l = new ContactsLoader(getActivity(), baseUri);
+ l.forceLoad();
+ return l;
}
@Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in.
- mAdapter.swapCursor(data);
+ public void onLoadFinished(Loader<Bundle> loader, Bundle data) {
+
+ mListAdapter.removeAll();
+ mGridAdapter.removeAll();
+ ArrayList<CallContact> tmp = data.getParcelableArrayList("Contacts");
+ ArrayList<CallContact> tmp2 = data.getParcelableArrayList("Starred");
+
+ Log.w(TAG, "Contact stareed " + tmp2.size());
+ mListAdapter.addAll(tmp);
+ mGridAdapter.addAll(tmp2);
+
}
@Override
- public void onLoaderReset(Loader<Cursor> loader) {
+ public void onLoaderReset(Loader<Bundle> loader) {
// Thi is called when the last Cursor provided to onLoadFinished
- mAdapter.swapCursor(null);
+ // mListAdapter.swapCursor(null);
}
}
diff --git a/src/com/savoirfairelinux/sflphone/fragments/DialingFragment.java b/src/com/savoirfairelinux/sflphone/fragments/DialingFragment.java
new file mode 100644
index 0000000..ccb28ce
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/fragments/DialingFragment.java
@@ -0,0 +1,56 @@
+package com.savoirfairelinux.sflphone.fragments;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.adapters.HistoryAdapter;
+import com.savoirfairelinux.sflphone.model.SipCall;
+import com.savoirfairelinux.sflphone.service.ISipService;
+
+public class DialingFragment extends Fragment{
+
+ private static final String TAG = HistoryFragment.class.getSimpleName();
+ public static final String ARG_SECTION_NUMBER = "section_number";
+ private boolean isReady;
+ private ISipService service;
+ HistoryAdapter mAdapter;
+
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // mAdapter = new HistoryAdapter(getActivity(),new ArrayList<HashMap<String, String>>());
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
+ View inflatedView = inflater.inflate(R.layout.frag_dialing, parent, false);
+
+ return inflatedView;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ }
+
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/loaders/ContactsLoader.java b/src/com/savoirfairelinux/sflphone/loaders/ContactsLoader.java
new file mode 100644
index 0000000..a56f78c
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/loaders/ContactsLoader.java
@@ -0,0 +1,83 @@
+package com.savoirfairelinux.sflphone.loaders;
+
+import java.util.ArrayList;
+
+import android.content.AsyncTaskLoader;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.Contacts;
+import android.util.Log;
+
+import com.savoirfairelinux.sflphone.model.CallContact;
+
+public class ContactsLoader extends AsyncTaskLoader<Bundle> {
+
+ private static final String TAG = ContactsLoader.class.getSimpleName();
+
+ // These are the Contacts rows that we will retrieve.
+ static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Contacts.PHOTO_ID, Contacts.LOOKUP_KEY, Contacts.STARRED };
+ static final String[] CONTACTS_PHONES_PROJECTION = new String[] { Phone.NUMBER, Phone.TYPE };
+ static final String[] CONTACTS_SIP_PROJECTION = new String[] { SipAddress.SIP_ADDRESS, SipAddress.TYPE };
+
+ String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + Contacts.DISPLAY_NAME + " != '' ))";
+ Uri baseUri;
+
+ public ContactsLoader(Context context, Uri u) {
+ super(context);
+ baseUri = u;
+ }
+
+ @Override
+ public Bundle loadInBackground() {
+ ArrayList<CallContact> contacts = new ArrayList<CallContact>();
+ ArrayList<CallContact> starred = new ArrayList<CallContact>();
+
+ Cursor result = getContext().getContentResolver().query(baseUri, CONTACTS_SUMMARY_PROJECTION, select, null,
+ Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
+ int iID = result.getColumnIndex(Contacts._ID);
+ int iName = result.getColumnIndex(Contacts.DISPLAY_NAME);
+ int iPhoto = result.getColumnIndex(Contacts.PHOTO_ID);
+ int iStarred = result.getColumnIndex(Contacts.STARRED);
+ CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance();
+
+ while (result.moveToNext()) {
+ builder.startNewContact(result.getLong(iID), result.getString(iName), result.getLong(iPhoto));
+
+// Cursor cPhones = getContext().getContentResolver().query(Phone.CONTENT_URI, CONTACTS_PHONES_PROJECTION,
+// Phone.CONTACT_ID + " =" + result.getLong(iID), null, null);
+
+// while (cPhones.moveToNext()) {
+// builder.addPhoneNumber(cPhones.getString(cPhones.getColumnIndex(Phone.NUMBER)), cPhones.getInt(cPhones.getColumnIndex(Phone.TYPE)));
+// Log.i(TAG,"Phone:"+cPhones.getString(cPhones.getColumnIndex(Phone.NUMBER)));
+// }
+// cPhones.close();
+//
+// Cursor cSip = getContext().getContentResolver().query(Phone.CONTENT_URI, CONTACTS_SIP_PROJECTION,
+// Phone.CONTACT_ID + "=" + result.getLong(iID), null, null);
+//
+// while (cSip.moveToNext()) {
+// builder.addSipNumber(cSip.getString(cSip.getColumnIndex(SipAddress.SIP_ADDRESS)), cSip.getInt(cSip.getColumnIndex(SipAddress.TYPE)));
+// Log.i(TAG,"Phone:"+cSip.getString(cSip.getColumnIndex(SipAddress.SIP_ADDRESS)));
+// }
+// cSip.close();
+
+ contacts.add(builder.build());
+ if (result.getInt(iStarred) == 1) {
+ starred.add(builder.build());
+ }
+
+ }
+
+ result.close();
+ Bundle toReturn = new Bundle();
+
+ toReturn.putParcelableArrayList("Contacts", contacts);
+ toReturn.putParcelableArrayList("Starred", starred);
+
+ return toReturn;
+ }
+}
diff --git a/src/com/savoirfairelinux/sflphone/model/CallContact.java b/src/com/savoirfairelinux/sflphone/model/CallContact.java
index fd3ea34..443c3b5 100644
--- a/src/com/savoirfairelinux/sflphone/model/CallContact.java
+++ b/src/com/savoirfairelinux/sflphone/model/CallContact.java
@@ -30,36 +30,195 @@
*/
package com.savoirfairelinux.sflphone.model;
-public class CallContact
-{
- private String mDisplayName;
- private String mPhone;
- private String mEmail;
+import java.util.ArrayList;
- public CallContact(String displayName, String phone, String email)
- {
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class CallContact implements Parcelable {
+
+ private long id;
+ private String mDisplayName;
+ private long photo_id;
+ ArrayList<Phone> phones, sip_phones;
+ String mEmail;
+
+ private CallContact(long cID, String displayName, long photoID, ArrayList<Phone> p, ArrayList<Phone> sip, String mail) {
+ id = cID;
mDisplayName = displayName;
- mPhone = phone;
- mEmail = email;
+ phones = p;
+ sip_phones = sip;
+ mEmail = mail;
+ photo_id = photoID;
}
- public String getDisplayName()
- {
+ public CallContact(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getmDisplayName() {
return mDisplayName;
}
- public String getPhone()
- {
- return mPhone;
+ public void setmDisplayName(String mDisplayName) {
+ this.mDisplayName = mDisplayName;
}
- public String getEmail()
- {
+ public long getPhoto_id() {
+ return photo_id;
+ }
+
+ public void setPhoto_id(long photo_id) {
+ this.photo_id = photo_id;
+ }
+
+ public ArrayList<Phone> getPhones() {
+ return phones;
+ }
+
+ public void setPhones(ArrayList<Phone> phones) {
+ this.phones = phones;
+ }
+
+ public ArrayList<Phone> getSip_phones() {
+ return sip_phones;
+ }
+
+ public void setSip_phones(ArrayList<Phone> sip_phones) {
+ this.sip_phones = sip_phones;
+ }
+
+ public String getmEmail() {
return mEmail;
}
- public String toString()
- {
+ public void setmEmail(String mEmail) {
+ this.mEmail = mEmail;
+ }
+
+ public String toString() {
return mDisplayName;
}
+
+ public static class ContactBuilder {
+
+ long contactID;
+ String contactName;
+ long contactPhoto;
+ ArrayList<Phone> phones;
+ ArrayList<Phone> sip;
+ String contactMail;
+ boolean hasPhoto;
+
+ public ContactBuilder startNewContact(long id, String displayName, long photo_id) {
+ contactID = id;
+ contactName = displayName;
+ contactPhoto = photo_id;
+ phones = new ArrayList<Phone>();
+ sip = new ArrayList<Phone>();
+ return this;
+ }
+
+ public ContactBuilder addPhoneNumber(String num, int type) {
+ phones.add(new Phone(num, type));
+ return this;
+ }
+
+ public ContactBuilder addSipNumber(String num, int type){
+ sip.add(new Phone(num, type));
+ return this;
+ }
+
+ public CallContact build() {
+ return new CallContact(contactID, contactName, contactPhoto, phones, sip, contactMail);
+ }
+
+ public static ContactBuilder getInstance() {
+ return new ContactBuilder();
+ }
+
+
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(id);
+ Phone[] tmp = new Phone[phones.size()];
+ phones.toArray(tmp);
+ dest.writeParcelableArray(tmp, flags);
+ dest.writeLong(photo_id);
+
+ }
+
+ private void readFromParcel(Parcel in) {
+
+ id = in.readLong();
+ mDisplayName = in.readString();
+ photo_id = in.readLong();
+ phones = in.readArrayList(Phone.class.getClassLoader());
+ sip_phones = in.readArrayList(Phone.class.getClassLoader());
+ mEmail = in.readString();
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ public CallContact createFromParcel(Parcel in) {
+ return new CallContact(in);
+ }
+
+ public CallContact[] newArray(int size) {
+ return new CallContact[size];
+ }
+ };
+
+ public static class Phone implements Parcelable {
+
+ int type;
+ String number;
+
+ public Phone(String num, int ty) {
+ type = ty;
+ number = num;
+ }
+
+ public Phone(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int arg1) {
+ dest.writeInt(type);
+ dest.writeString(number);
+ }
+
+ private void readFromParcel(Parcel in) {
+ type = in.readInt();
+ number = in.readString();
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ public Phone createFromParcel(Parcel in) {
+ return new Phone(in);
+ }
+
+ public Phone[] newArray(int size) {
+ return new Phone[size];
+ }
+ };
+
+ }
+
}
diff --git a/src/com/savoirfairelinux/sflphone/model/ContactManager.java b/src/com/savoirfairelinux/sflphone/model/ContactManager.java
deleted file mode 100644
index 861b0ad..0000000
--- a/src/com/savoirfairelinux/sflphone/model/ContactManager.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
- *
- * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Additional permission under GNU GPL version 3 section 7:
- *
- * If you modify this program, or any covered work, by linking or
- * combining it with the OpenSSL project's OpenSSL library (or a
- * modified version of that library), containing parts covered by the
- * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- * grants you additional permission to convey the resulting work.
- * Corresponding Source for a non-source form of such a combination
- * shall include the source code for the parts of OpenSSL used as well
- * as that of the covered work.
- */
-package com.savoirfairelinux.sflphone.model;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.util.Log;
-import java.util.ArrayList;
-
-
-public class ContactManager
-{
- int mCount;
- Context mContext;
- ArrayList<CallContact> contactList;
-
- static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME,
- Contacts.PHOTO_ID, Contacts.LOOKUP_KEY };
-
- public ContactManager(Context context)
- {
- mCount = 0;
- mContext = context;
- contactList = new ArrayList<CallContact>();
-
- loadContactList();
- }
-
- public void loadContactList()
- {
- ContentResolver resolver = mContext.getContentResolver();
-
- Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, CONTACTS_SUMMARY_PROJECTION, null, null, null);
- while(cursor.moveToNext()) {
- mCount++;
- String displayName = "";
- String phoneNumber = "";
- String emailAddress = "";
-
- String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
-
- displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
-
- /*
- Cursor structuredName = resolver.query(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, null,
- ContactsContract.Contacts._ID +" = "+ contactId, null, null);
- if(structureName.getCount() > 0)
- Log.i("loadContactList", "Got a given name");
- */
-
- /*
- Cursor sipAddress = resolver.query(ContactsContract.Contacts.SIP_ADDRESS, null,
- ContactsContract.Contacts._ID +" = "+ contactId, null, null);
- if(sipAddress.getCount() > 0)
- Log.i("loadContactList", "Got a sip address");
- */
-
- String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
- if(hasPhone.compareTo("1") == 0) {
- // You know it has a number so now query it like this
- Cursor phones = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
- ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
- while(phones.moveToNext()) {
- phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
- }
- phones.close();
- }
-
- Cursor emails = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
- ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null);
- while (emails.moveToNext()) {
- // This would allow you get several email addresses
- emailAddress = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
- }
- emails.close();
-
- contactList.add(new CallContact(displayName, phoneNumber, emailAddress));
-
- }
- cursor.close();
- }
-
- public int getNbContacts()
- {
- return mCount;
- }
-
- public CallContact getContact(int position)
- {
- return contactList.get(position);
- }
-
- public ArrayList<CallContact> getContactList()
- {
- return contactList;
- }
-}
-
diff --git a/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java b/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java
index 310e5d8..9521c21 100644
--- a/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java
+++ b/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java
@@ -83,20 +83,20 @@
return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAccountList(swigCPtr, this), true);
}
- public SWIGTYPE_p_std__vectorT_int32_t_t getAudioCodecList() {
- return new SWIGTYPE_p_std__vectorT_int32_t_t(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioCodecList(swigCPtr, this), true);
+ public IntVect getAudioCodecList() {
+ return new IntVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioCodecList(swigCPtr, this), true);
}
public StringVect getSupportedTlsMethod() {
return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getSupportedTlsMethod(swigCPtr, this), true);
}
- public StringVect getAudioCodecDetails(SWIGTYPE_p_int32_t payload) {
- return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioCodecDetails(swigCPtr, this, SWIGTYPE_p_int32_t.getCPtr(payload)), true);
+ public StringVect getAudioCodecDetails(int payload) {
+ return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioCodecDetails(swigCPtr, this, payload), true);
}
- public SWIGTYPE_p_std__vectorT_int32_t_t getActiveAudioCodecList(String accountID) {
- return new SWIGTYPE_p_std__vectorT_int32_t_t(SFLPhoneserviceJNI.ConfigurationManagerJNI_getActiveAudioCodecList(swigCPtr, this, accountID), true);
+ public IntVect getActiveAudioCodecList(String accountID) {
+ return new IntVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getActiveAudioCodecList(swigCPtr, this, accountID), true);
}
public void setActiveAudioCodecList(StringVect list, String accountID) {
@@ -119,24 +119,24 @@
return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioInputDeviceList(swigCPtr, this), true);
}
- public void setAudioOutputDevice(SWIGTYPE_p_int32_t index) {
- SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioOutputDevice(swigCPtr, this, SWIGTYPE_p_int32_t.getCPtr(index));
+ public void setAudioOutputDevice(int index) {
+ SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioOutputDevice(swigCPtr, this, index);
}
- public void setAudioInputDevice(SWIGTYPE_p_int32_t index) {
- SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioInputDevice(swigCPtr, this, SWIGTYPE_p_int32_t.getCPtr(index));
+ public void setAudioInputDevice(int index) {
+ SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioInputDevice(swigCPtr, this, index);
}
- public void setAudioRingtoneDevice(SWIGTYPE_p_int32_t index) {
- SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioRingtoneDevice(swigCPtr, this, SWIGTYPE_p_int32_t.getCPtr(index));
+ public void setAudioRingtoneDevice(int index) {
+ SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioRingtoneDevice(swigCPtr, this, index);
}
public StringVect getCurrentAudioDevicesIndex() {
return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getCurrentAudioDevicesIndex(swigCPtr, this), true);
}
- public SWIGTYPE_p_int32_t getAudioDeviceIndex(String name) {
- return new SWIGTYPE_p_int32_t(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioDeviceIndex(swigCPtr, this, name), true);
+ public int getAudioDeviceIndex(String name) {
+ return SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioDeviceIndex(swigCPtr, this, name);
}
public String getCurrentAudioOutputPlugin() {
@@ -167,20 +167,20 @@
return SFLPhoneserviceJNI.ConfigurationManagerJNI_getEchoCancelTailLength(swigCPtr, this);
}
- public void setEchoCancelTailLength(SWIGTYPE_p_int32_t length) {
- SFLPhoneserviceJNI.ConfigurationManagerJNI_setEchoCancelTailLength(swigCPtr, this, SWIGTYPE_p_int32_t.getCPtr(length));
+ public void setEchoCancelTailLength(int length) {
+ SFLPhoneserviceJNI.ConfigurationManagerJNI_setEchoCancelTailLength(swigCPtr, this, length);
}
public int getEchoCancelDelay() {
return SFLPhoneserviceJNI.ConfigurationManagerJNI_getEchoCancelDelay(swigCPtr, this);
}
- public void setEchoCancelDelay(SWIGTYPE_p_int32_t delay) {
- SFLPhoneserviceJNI.ConfigurationManagerJNI_setEchoCancelDelay(swigCPtr, this, SWIGTYPE_p_int32_t.getCPtr(delay));
+ public void setEchoCancelDelay(int delay) {
+ SFLPhoneserviceJNI.ConfigurationManagerJNI_setEchoCancelDelay(swigCPtr, this, delay);
}
- public SWIGTYPE_p_int32_t isIax2Enabled() {
- return new SWIGTYPE_p_int32_t(SFLPhoneserviceJNI.ConfigurationManagerJNI_isIax2Enabled(swigCPtr, this), true);
+ public int isIax2Enabled() {
+ return SFLPhoneserviceJNI.ConfigurationManagerJNI_isIax2Enabled(swigCPtr, this);
}
public String getRecordPath() {
@@ -203,16 +203,16 @@
SFLPhoneserviceJNI.ConfigurationManagerJNI_setRecordingCall(swigCPtr, this, id);
}
- public SWIGTYPE_p_int32_t getHistoryLimit() {
- return new SWIGTYPE_p_int32_t(SFLPhoneserviceJNI.ConfigurationManagerJNI_getHistoryLimit(swigCPtr, this), true);
+ public int getHistoryLimit() {
+ return SFLPhoneserviceJNI.ConfigurationManagerJNI_getHistoryLimit(swigCPtr, this);
}
public void clearHistory() {
SFLPhoneserviceJNI.ConfigurationManagerJNI_clearHistory(swigCPtr, this);
}
- public void setHistoryLimit(SWIGTYPE_p_int32_t days) {
- SFLPhoneserviceJNI.ConfigurationManagerJNI_setHistoryLimit(swigCPtr, this, SWIGTYPE_p_int32_t.getCPtr(days));
+ public void setHistoryLimit(int days) {
+ SFLPhoneserviceJNI.ConfigurationManagerJNI_setHistoryLimit(swigCPtr, this, days);
}
public void setAudioManager(String api) {
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
index 2450f97..9b7b80f 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
@@ -17,6 +17,7 @@
void setAccountDetails(in String accountId, in Map accountDetails);
void setAudioPlugin(in String callID);
String getCurrentAudioOutputPlugin();
+ List getAudioCodecList(in String accountID);
/* History */
List getHistory();
diff --git a/src/com/savoirfairelinux/sflphone/service/IntVect.java b/src/com/savoirfairelinux/sflphone/service/IntVect.java
new file mode 100644
index 0000000..8133c01
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/service/IntVect.java
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.8
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package com.savoirfairelinux.sflphone.service;
+
+public class IntVect {
+ private long swigCPtr;
+ protected boolean swigCMemOwn;
+
+ protected IntVect(long cPtr, boolean cMemoryOwn) {
+ swigCMemOwn = cMemoryOwn;
+ swigCPtr = cPtr;
+ }
+
+ protected static long getCPtr(IntVect obj) {
+ return (obj == null) ? 0 : obj.swigCPtr;
+ }
+
+ protected void finalize() {
+ delete();
+ }
+
+ public synchronized void delete() {
+ if (swigCPtr != 0) {
+ if (swigCMemOwn) {
+ swigCMemOwn = false;
+ SFLPhoneserviceJNI.delete_IntVect(swigCPtr);
+ }
+ swigCPtr = 0;
+ }
+ }
+
+ public IntVect() {
+ this(SFLPhoneserviceJNI.new_IntVect__SWIG_0(), true);
+ }
+
+ public IntVect(long n) {
+ this(SFLPhoneserviceJNI.new_IntVect__SWIG_1(n), true);
+ }
+
+ public long size() {
+ return SFLPhoneserviceJNI.IntVect_size(swigCPtr, this);
+ }
+
+ public long capacity() {
+ return SFLPhoneserviceJNI.IntVect_capacity(swigCPtr, this);
+ }
+
+ public void reserve(long n) {
+ SFLPhoneserviceJNI.IntVect_reserve(swigCPtr, this, n);
+ }
+
+ public boolean isEmpty() {
+ return SFLPhoneserviceJNI.IntVect_isEmpty(swigCPtr, this);
+ }
+
+ public void clear() {
+ SFLPhoneserviceJNI.IntVect_clear(swigCPtr, this);
+ }
+
+ public void add(int x) {
+ SFLPhoneserviceJNI.IntVect_add(swigCPtr, this, x);
+ }
+
+ public int get(int i) {
+ return SFLPhoneserviceJNI.IntVect_get(swigCPtr, this, i);
+ }
+
+ public void set(int i, int val) {
+ SFLPhoneserviceJNI.IntVect_set(swigCPtr, this, i, val);
+ }
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/service/SipService.java b/src/com/savoirfairelinux/sflphone/service/SipService.java
index 03b5233..3534dc7 100644
--- a/src/com/savoirfairelinux/sflphone/service/SipService.java
+++ b/src/com/savoirfairelinux/sflphone/service/SipService.java
@@ -47,6 +47,7 @@
import android.widget.Toast;
import com.savoirfairelinux.sflphone.account.AccountDetailsHandler;
+import com.savoirfairelinux.sflphone.account.AudioHandler;
import com.savoirfairelinux.sflphone.account.HistoryHandler;
import com.savoirfairelinux.sflphone.client.SFLphoneApplication;
@@ -440,7 +441,7 @@
CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
getExecutor().execute(runInstance);
while (!runInstance.isDone()) {
- Log.e(TAG, "Waiting for Nofing");
+// Log.e(TAG, "Waiting for Nofing");
}
return (String) runInstance.getVal();
}
@@ -458,7 +459,7 @@
AccountList runInstance = new AccountList();
getExecutor().execute(runInstance);
while (!runInstance.isDone()) {
- Log.e(TAG, "Waiting for Nofing");
+// Log.e(TAG, "Waiting for Nofing");
}
StringVect swigvect = (StringVect) runInstance.getVal();
@@ -536,7 +537,7 @@
AddAccount runInstance = new AddAccount(swigmap);
getExecutor().execute(runInstance);
while (!runInstance.isDone()) {
- Log.e(TAG, "Waiting for Nofing");
+// Log.e(TAG, "Waiting for Nofing");
}
String accountId = (String) runInstance.getVal();
@@ -574,7 +575,7 @@
History runInstance = new History();
getExecutor().execute(runInstance);
while (!runInstance.isDone()) {
- Log.w(TAG, "Waiting for getHistory");
+// Log.w(TAG, "Waiting for getHistory");
}
VectMap swigmap = (VectMap) runInstance.getVal();
@@ -760,7 +761,7 @@
ConfList runInstance = new ConfList();
getExecutor().execute(runInstance);
while (!runInstance.isDone()) {
- Log.w(TAG, "Waiting for getConferenceList");
+// Log.w(TAG, "Waiting for getConferenceList");
}
StringVect swigvect = (StringVect) runInstance.getVal();
@@ -804,7 +805,7 @@
RecordPath runInstance = new RecordPath();
getExecutor().execute(runInstance);
while (!runInstance.isDone()) {
- Log.w(TAG, "Waiting for getRecordPath");
+// Log.w(TAG, "Waiting for getRecordPath");
}
String path = (String) runInstance.getVal();
@@ -846,5 +847,28 @@
}
+ @Override
+ public List getAudioCodecList(String accountID) throws RemoteException {
+ class AudioCodecList extends SipRunnableWithReturn {
+
+ @Override
+ protected IntVect doRun() throws SameThreadException {
+ Log.i(TAG, "SipService.getAudioCodecList() thread running...");
+ return configurationManagerJNI.getAudioCodecList();
+ }
+ }
+
+ AudioCodecList runInstance = new AudioCodecList();
+ getExecutor().execute(runInstance);
+ while (!runInstance.isDone()) {
+ Log.w(TAG, "Waiting for getAudioCodecList");
+ }
+ IntVect swigmap = (IntVect) runInstance.getVal();
+
+ ArrayList<Integer> codecs = AudioHandler.convertSwigToNative(swigmap);
+
+ return codecs;
+ }
+
};
}
diff --git a/src/com/savoirfairelinux/sflphone/views/ClearableEditText.java b/src/com/savoirfairelinux/sflphone/views/ClearableEditText.java
new file mode 100644
index 0000000..6938759
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/views/ClearableEditText.java
@@ -0,0 +1,88 @@
+package com.savoirfairelinux.sflphone.views;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.RelativeLayout;
+
+import com.savoirfairelinux.sflphone.R;
+
+public class ClearableEditText extends RelativeLayout {
+ LayoutInflater inflater = null;
+ EditText edit_text;
+ Button btn_clear;
+
+ public ClearableEditText(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ // TODO Auto-generated constructor stub
+ initViews();
+ }
+
+ public ClearableEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ // TODO Auto-generated constructor stub
+ initViews();
+ }
+
+ public ClearableEditText(Context context) {
+ super(context);
+ // TODO Auto-generated constructor stub
+ initViews();
+ }
+
+ void initViews() {
+ inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.clearable_edit_text, this, true);
+ edit_text = (EditText) findViewById(R.id.clearable_edit);
+ btn_clear = (Button) findViewById(R.id.clearable_button_clear);
+ btn_clear.setVisibility(RelativeLayout.INVISIBLE);
+ clearText();
+ showHideClearButton();
+ }
+
+ void clearText() {
+ btn_clear.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // TODO Auto-generated method stub
+ edit_text.setText("");
+ }
+ });
+ }
+
+ void showHideClearButton() {
+ edit_text.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // TODO Auto-generated method stub
+ if (s.length() > 0)
+ btn_clear.setVisibility(RelativeLayout.VISIBLE);
+ else
+ btn_clear.setVisibility(RelativeLayout.INVISIBLE);
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ }
+
+ public Editable getText() {
+ Editable text = edit_text.getText();
+ return text;
+ }
+}
diff --git a/src/com/savoirfairelinux/sflphone/views/TACGridView.java b/src/com/savoirfairelinux/sflphone/views/TACGridView.java
new file mode 100644
index 0000000..38c2fc6
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/views/TACGridView.java
@@ -0,0 +1,48 @@
+package com.savoirfairelinux.sflphone.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.GridView;
+
+public class TACGridView extends GridView {
+
+ public TACGridView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ }
+
+ public TACGridView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public TACGridView(Context context) {
+ super(context);
+ }
+
+ boolean expanded = false;
+
+ public boolean isExpanded() {
+ return expanded;
+ }
+
+ public void setExpanded(boolean expanded) {
+ this.expanded = expanded;
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (isExpanded()) {
+ // Calculate entire height by providing a very large height hint.
+ // But do not use the highest 2 bits of this integer; those are
+ // reserved for the MeasureSpec mode.
+ int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, expandSpec);
+
+ android.view.ViewGroup.LayoutParams params = getLayoutParams();
+ params.height = getMeasuredHeight();
+ } else {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+ }
+
+}