diff --git a/res/drawable-xhdpi/button_alert_background_default.9.png b/res/drawable-xhdpi/button_alert_background_default.9.png
new file mode 100644
index 000000000..b8857340d
Binary files /dev/null and b/res/drawable-xhdpi/button_alert_background_default.9.png differ
diff --git a/res/drawable-xhdpi/button_alert_background_over.9.png b/res/drawable-xhdpi/button_alert_background_over.9.png
new file mode 100644
index 000000000..f42b202ff
Binary files /dev/null and b/res/drawable-xhdpi/button_alert_background_over.9.png differ
diff --git a/res/drawable/alert.xml b/res/drawable/alert.xml
new file mode 100644
index 000000000..125848d4c
--- /dev/null
+++ b/res/drawable/alert.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/contact.xml b/res/layout/contact.xml
index 627bef0f7..040e12e04 100644
--- a/res/layout/contact.xml
+++ b/res/layout/contact.xml
@@ -22,22 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
- android:adjustViewBounds="true"
- android:layout_weight="1"/>
-
-
+ android:adjustViewBounds="true"/>
diff --git a/res/layout/contact_delete_button.xml b/res/layout/contact_delete_button.xml
new file mode 100644
index 000000000..90af7a399
--- /dev/null
+++ b/res/layout/contact_delete_button.xml
@@ -0,0 +1,14 @@
+
+
+
\ No newline at end of file
diff --git a/res/layout/contact_edit_row.xml b/res/layout/contact_edit_row.xml
new file mode 100644
index 000000000..4c6b13a80
--- /dev/null
+++ b/res/layout/contact_edit_row.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/edit_contact.xml b/res/layout/edit_contact.xml
index ac8f68cc2..0e230638a 100644
--- a/res/layout/edit_contact.xml
+++ b/res/layout/edit_contact.xml
@@ -63,10 +63,25 @@
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:background="@drawable/chat_fast_address_background"
- android:gravity="center"
+ android:gravity="left"
android:paddingRight="5dp"
android:inputType="textPersonName|textCapWords"/>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/org/linphone/ContactFragment.java b/src/org/linphone/ContactFragment.java
index a623423b0..680d5c135 100644
--- a/src/org/linphone/ContactFragment.java
+++ b/src/org/linphone/ContactFragment.java
@@ -39,7 +39,7 @@ import android.widget.TextView;
*/
public class ContactFragment extends Fragment implements OnClickListener {
private Contact contact;
- private TextView editContact, newContact;
+ private TextView editContact;
private LayoutInflater inflater;
private View view;
private boolean displayChatAddressOnly = false;
@@ -70,10 +70,6 @@ public class ContactFragment extends Fragment implements OnClickListener {
editContact = (TextView) view.findViewById(R.id.editContact);
editContact.setOnClickListener(this);
- newContact = (TextView) view.findViewById(R.id.newContact);
- if (newContact != null) {
- newContact.setOnClickListener(this);
- }
return view;
}
@@ -186,10 +182,6 @@ public class ContactFragment extends Fragment implements OnClickListener {
case R.id.editContact:
LinphoneActivity.instance().editContact(contact);
break;
-
- case R.id.newContact:
- LinphoneActivity.instance().addContact("", "");
- break;
}
}
}
diff --git a/src/org/linphone/EditContactFragment.java b/src/org/linphone/EditContactFragment.java
index 81e18b1ba..80c33c84d 100644
--- a/src/org/linphone/EditContactFragment.java
+++ b/src/org/linphone/EditContactFragment.java
@@ -1,8 +1,14 @@
package org.linphone;
+import java.io.InputStream;
import java.util.ArrayList;
+import java.util.List;
+
+import org.linphone.compatibility.Compatibility;
+import org.linphone.ui.AvatarWithShadow;
import android.content.ContentProviderOperation;
+import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;
@@ -14,17 +20,23 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TableLayout;
import android.widget.TextView;
public class EditContactFragment extends Fragment {
private View view;
private TextView ok;
private EditText displayName;
+ private LayoutInflater inflater;
private boolean isNewContact = true;
private int contactID;
+ private List numbersAndAddresses;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ this.inflater = inflater;
+
Contact contact = null;
if (getArguments() != null && getArguments().getSerializable("Contact") != null) {
contact = (Contact) getArguments().getSerializable("Contact");
@@ -51,6 +63,11 @@ public class EditContactFragment extends Fragment {
} else {
updateExistingContact();
}
+
+ for (NewOrUpdatedNumberOrAddress numberOrAddress : numbersAndAddresses) {
+ numberOrAddress.save();
+ }
+
getFragmentManager().popBackStackImmediate();
}
});
@@ -74,13 +91,85 @@ public class EditContactFragment extends Fragment {
public void afterTextChanged(Editable s) {
}
});
+
if (!isNewContact) {
displayName.setText(contact.getName());
}
+ AvatarWithShadow contactPicture = (AvatarWithShadow) view.findViewById(R.id.contactPicture);
+ if (contact != null && contact.getPhotoUri() != null) {
+ InputStream input = Compatibility.getContactPictureInputStream(getActivity().getContentResolver(), contact.getID());
+ contactPicture.setImageBitmap(BitmapFactory.decodeStream(input));
+ } else {
+ contactPicture.setImageResource(R.drawable.unknown_small);
+ }
+
+ initNumbersFields((TableLayout) view.findViewById(R.id.controls), contact);
+
return view;
}
+ private void initNumbersFields(TableLayout controls, final Contact contact) {
+ controls.removeAllViews();
+ numbersAndAddresses = new ArrayList();
+
+ if (contact != null) {
+ for (String numberOrAddress : contact.getNumerosOrAddresses()) {
+ boolean isSip = numberOrAddress.startsWith("sip:");
+ if (isSip) {
+ numberOrAddress = numberOrAddress.replace("sip:", "");
+ }
+
+ final NewOrUpdatedNumberOrAddress nounoa = new NewOrUpdatedNumberOrAddress(numberOrAddress, isSip);
+ numbersAndAddresses.add(nounoa);
+
+ final View view = inflater.inflate(R.layout.contact_edit_row, null);
+
+ final EditText noa = (EditText) view.findViewById(R.id.numoraddr);
+ noa.setText(numberOrAddress);
+ noa.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ nounoa.setNewNumberOrAddress(noa.getText().toString());
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+ });
+
+ ImageView delete = (ImageView) view.findViewById(R.id.delete);
+ delete.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ nounoa.delete();
+ view.setVisibility(View.GONE);
+ }
+ });
+
+ controls.addView(view);
+ }
+
+ if (!isNewContact) {
+ View deleteContact = inflater.inflate(R.layout.contact_delete_button, null);
+ deleteContact.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ deleteExistingContact();
+ LinphoneActivity.instance().removeContactFromLists(contact);
+ LinphoneActivity.instance().displayContacts(false);
+ }
+ });
+ controls.addView(deleteContact);
+ }
+
+ }
+ }
+
private void createNewContact() {
ArrayList ops = new ArrayList();
contactID = ops.size();
@@ -93,14 +182,15 @@ public class EditContactFragment extends Fragment {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, contactID)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
- .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName.getText().toString()).build()
+ .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName.getText().toString())
+ .build()
);
}
try {
getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
-
+ e.printStackTrace();
}
}
@@ -108,20 +198,140 @@ public class EditContactFragment extends Fragment {
ArrayList ops = new ArrayList();
if (displayName.getText().length() > 0) {
- String selectPhone = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'" ;
- String[] phoneArgs = new String[] { String.valueOf(contactID) };
+ String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'" ;
+ String[] args = new String[] { String.valueOf(contactID) };
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
- .withSelection(selectPhone, phoneArgs)
+ .withSelection(select, args)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
- .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName.getText().toString()).build()
+ .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName.getText().toString())
+ .build()
);
}
try {
getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
-
+ e.printStackTrace();
}
}
+
+ private void deleteExistingContact() {
+ ArrayList ops = new ArrayList();
+
+ if (displayName.getText().length() > 0) {
+ String select = ContactsContract.Data.CONTACT_ID + "=?";
+ String[] args = new String[] { String.valueOf(contactID) };
+
+ ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
+ .withSelection(select, args)
+ .build()
+ );
+ }
+
+ try {
+ getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ class NewOrUpdatedNumberOrAddress {
+ private String oldNumberOrAddress;
+ private String newNumberOrAddress;
+ private boolean isSipAddress;
+
+ public NewOrUpdatedNumberOrAddress(boolean isSip) {
+ oldNumberOrAddress = null;
+ newNumberOrAddress = null;
+ isSipAddress = isSip;
+ }
+
+ public NewOrUpdatedNumberOrAddress(String old, boolean isSip) {
+ oldNumberOrAddress = old;
+ newNumberOrAddress = null;
+ isSipAddress = isSip;
+ }
+
+ public void setNewNumberOrAddress(String newN) {
+ newNumberOrAddress = newN;
+ }
+
+ public void save() {
+ if (newNumberOrAddress == null || newNumberOrAddress.equals(oldNumberOrAddress))
+ return;
+
+ ArrayList ops = new ArrayList();
+
+ if (oldNumberOrAddress == null) {
+ // New number to add
+ addNewNumber(ops);
+ } else {
+ // Old number to update
+ updateNumber(ops);
+ }
+
+ try {
+ getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void delete() {
+ //TODO
+ }
+
+ private void addNewNumber(ArrayList ops) {
+ if (isSipAddress) {
+ ops.add(ContentProviderOperation.
+ newInsert(ContactsContract.Data.CONTENT_URI)
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, contactID)
+ .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
+ .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newNumberOrAddress)
+ .withValue(ContactsContract.CommonDataKinds.SipAddress.TYPE, ContactsContract.CommonDataKinds.SipAddress.TYPE_CUSTOM)
+ .withValue(ContactsContract.CommonDataKinds.SipAddress.LABEL, "Linphone")
+ .build()
+ );
+ } else {
+ ops.add(ContentProviderOperation.
+ newInsert(ContactsContract.Data.CONTENT_URI)
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, contactID)
+ .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
+ .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, newNumberOrAddress)
+ .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM)
+ .withValue(ContactsContract.CommonDataKinds.Phone.LABEL, "Linphone")
+ .build()
+ );
+ }
+ }
+
+ private void updateNumber(ArrayList ops) {
+ if (isSipAddress) {
+ String select = ContactsContract.Data.CONTACT_ID + "=? AND "
+ + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND "
+ + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?";
+ String[] args = new String[] { String.valueOf(contactID), oldNumberOrAddress };
+
+ ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+ .withSelection(select, args)
+ .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
+ .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newNumberOrAddress)
+ .build()
+ );
+ } else {
+ String select = ContactsContract.Data.CONTACT_ID + "=? AND "
+ + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "' AND "
+ + ContactsContract.CommonDataKinds.Phone.NUMBER + "=?";
+ String[] args = new String[] { String.valueOf(contactID), oldNumberOrAddress };
+
+ ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+ .withSelection(select, args)
+ .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
+ .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, newNumberOrAddress)
+ .build()
+ );
+ }
+ }
+ }
}
diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java
index f9ebd4860..036ce7e17 100644
--- a/src/org/linphone/LinphoneActivity.java
+++ b/src/org/linphone/LinphoneActivity.java
@@ -1075,6 +1075,17 @@ public class LinphoneActivity extends FragmentActivity implements
}
}
}
+
+ public void removeContactFromLists(Contact contact) {
+ if (contactList.contains(contact)) {
+ contactList.remove(contact);
+ contactCursor = Compatibility.getContactsCursor(getContentResolver());
+ }
+ if (sipContactList.contains(contact)) {
+ sipContactList.remove(contact);
+ sipContactCursor = Compatibility.getSIPContactsCursor(getContentResolver());
+ }
+ }
private synchronized void prepareContactsInBackground() {
if (contactCursor != null) {
@@ -1110,10 +1121,11 @@ public class LinphoneActivity extends FragmentActivity implements
}
}
});
- sipContactsHandler.start();
contactList = new ArrayList();
sipContactList = new ArrayList();
+
+ sipContactsHandler.start();
}
private void initInCallMenuLayout(boolean callTransfer) {