Merge pull request from SimpleMobileTools/master

upd
This commit is contained in:
solokot 2019-09-16 10:52:06 +03:00 committed by GitHub
commit 0841fa461c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 553 additions and 325 deletions

@ -1,6 +1,13 @@
Changelog Changelog
========== ==========
Version 6.4.0 *(2019-09-15)*
----------------------------
* Removed the setting for merging duplicate contacts, merge them always
* Show all contact sources of the contact at the View screen
* Fixed a glitch with some missing fields at exporting contacts in .ics files
Version 6.3.5 *(2019-08-27)* Version 6.3.5 *(2019-08-27)*
---------------------------- ----------------------------

@ -15,8 +15,8 @@ android {
applicationId "com.simplemobiletools.contacts.pro" applicationId "com.simplemobiletools.contacts.pro"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 46 versionCode 47
versionName "6.3.5" versionName "6.4.0"
setProperty("archivesBaseName", "contacts") setProperty("archivesBaseName", "contacts")
} }
@ -51,7 +51,7 @@ android {
} }
dependencies { dependencies {
implementation 'com.simplemobiletools:commons:5.16.17' implementation 'com.simplemobiletools:commons:5.17.17'
implementation 'joda-time:joda-time:2.10.1' implementation 'joda-time:joda-time:2.10.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
implementation 'com.googlecode.ez-vcard:ez-vcard:0.10.5' implementation 'com.googlecode.ez-vcard:ez-vcard:0.10.5'

@ -51,7 +51,7 @@ abstract class ContactActivity : SimpleActivity() {
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop() .centerCrop()
if (isDestroyed) { if (isDestroyed || isFinishing) {
return return
} }
@ -77,14 +77,15 @@ abstract class ContactActivity : SimpleActivity() {
fun deleteContact() { fun deleteContact() {
ConfirmationDialog(this) { ConfirmationDialog(this) {
if (contact != null) { if (contact != null) {
ContactsHelper(this).deleteContact(contact!!) ContactsHelper(this).deleteContact(contact!!, false) {
finish() finish()
}
} }
} }
} }
fun shareContact() { fun shareContact(contact: Contact) {
shareContacts(arrayListOf(contact!!)) shareContacts(arrayListOf(contact))
} }
fun trySendSMS() { fun trySendSMS() {
@ -179,8 +180,8 @@ abstract class ContactActivity : SimpleActivity() {
} }
fun getEventTextId(type: Int) = when (type) { fun getEventTextId(type: Int) = when (type) {
ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY -> R.string.birthday
ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY -> R.string.anniversary ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY -> R.string.anniversary
ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY -> R.string.birthday
else -> R.string.other else -> R.string.other
} }
} }

@ -108,7 +108,7 @@ class EditContactActivity : ContactActivity() {
when (item.itemId) { when (item.itemId) {
R.id.save -> saveContact() R.id.save -> saveContact()
R.id.share -> shareContact() R.id.share -> shareContact(contact!!)
R.id.open_with -> openWith() R.id.open_with -> openWith()
R.id.delete -> deleteContact() R.id.delete -> deleteContact()
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
@ -821,8 +821,8 @@ class EditContactActivity : ContactActivity() {
private fun showEventTypePicker(eventTypeField: TextView) { private fun showEventTypePicker(eventTypeField: TextView) {
val items = arrayListOf( val items = arrayListOf(
RadioItem(CommonDataKinds.Event.TYPE_BIRTHDAY, getString(R.string.birthday)),
RadioItem(CommonDataKinds.Event.TYPE_ANNIVERSARY, getString(R.string.anniversary)), RadioItem(CommonDataKinds.Event.TYPE_ANNIVERSARY, getString(R.string.anniversary)),
RadioItem(CommonDataKinds.Event.TYPE_BIRTHDAY, getString(R.string.birthday)),
RadioItem(CommonDataKinds.Event.TYPE_OTHER, getString(R.string.other)) RadioItem(CommonDataKinds.Event.TYPE_OTHER, getString(R.string.other))
) )
@ -992,10 +992,14 @@ class EditContactActivity : ContactActivity() {
if (ContactsHelper(this@EditContactActivity).insertContact(contact!!)) { if (ContactsHelper(this@EditContactActivity).insertContact(contact!!)) {
if (deleteCurrentContact) { if (deleteCurrentContact) {
contact!!.source = originalContactSource contact!!.source = originalContactSource
ContactsHelper(this).deleteContact(contact!!) ContactsHelper(this).deleteContact(contact!!, false) {
setResult(Activity.RESULT_OK)
finish()
}
} else {
setResult(Activity.RESULT_OK)
finish()
} }
setResult(Activity.RESULT_OK)
finish()
} else { } else {
toast(R.string.unknown_error_occurred) toast(R.string.unknown_error_occurred)
} }
@ -1217,8 +1221,8 @@ class EditContactActivity : ContactActivity() {
} }
private fun getEventTypeId(value: String) = when (value) { private fun getEventTypeId(value: String) = when (value) {
getString(R.string.birthday) -> CommonDataKinds.Event.TYPE_BIRTHDAY
getString(R.string.anniversary) -> CommonDataKinds.Event.TYPE_ANNIVERSARY getString(R.string.anniversary) -> CommonDataKinds.Event.TYPE_ANNIVERSARY
getString(R.string.birthday) -> CommonDataKinds.Event.TYPE_BIRTHDAY
else -> CommonDataKinds.Event.TYPE_OTHER else -> CommonDataKinds.Event.TYPE_OTHER
} }

@ -58,7 +58,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
private var storedShowContactThumbnails = false private var storedShowContactThumbnails = false
private var storedShowPhoneNumbers = false private var storedShowPhoneNumbers = false
private var storedStartNameWithSurname = false private var storedStartNameWithSurname = false
private var storedFilterDuplicates = true
private var storedShowTabs = 0 private var storedShowTabs = 0
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -137,10 +136,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname) favorites_fragment?.startNameWithSurnameChanged(configStartNameWithSurname)
} }
if (storedFilterDuplicates != config.filterDuplicates) {
refreshContacts(ALL_TABS_MASK)
}
if (werePermissionsHandled && !isFirstResume) { if (werePermissionsHandled && !isFirstResume) {
if (viewpager.adapter == null) { if (viewpager.adapter == null) {
initFragments() initFragments()
@ -213,7 +208,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
storedShowContactThumbnails = showContactThumbnails storedShowContactThumbnails = showContactThumbnails
storedShowPhoneNumbers = showPhoneNumbers storedShowPhoneNumbers = showPhoneNumbers
storedStartNameWithSurname = startNameWithSurname storedStartNameWithSurname = startNameWithSurname
storedFilterDuplicates = filterDuplicates
storedShowTabs = showTabs storedShowTabs = showTabs
} }
} }
@ -527,7 +521,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
} }
override fun refreshContacts(refreshTabsMask: Int) { override fun refreshContacts(refreshTabsMask: Int) {
if (isDestroyed || isGettingContacts) { if (isDestroyed || isFinishing || isGettingContacts) {
return return
} }
@ -540,7 +534,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
ContactsHelper(this).getContacts { contacts -> ContactsHelper(this).getContacts { contacts ->
isGettingContacts = false isGettingContacts = false
if (isDestroyed) { if (isDestroyed || isFinishing) {
return@getContacts return@getContacts
} }
@ -575,6 +569,7 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
add(Release(34, R.string.release_34)) add(Release(34, R.string.release_34))
add(Release(39, R.string.release_39)) add(Release(39, R.string.release_39))
add(Release(40, R.string.release_40)) add(Release(40, R.string.release_40))
add(Release(47, R.string.release_47))
checkWhatsNew(this, BuildConfig.VERSION_CODE) checkWhatsNew(this, BuildConfig.VERSION_CODE)
} }
} }

@ -84,7 +84,7 @@ class SelectContactActivity : SimpleActivity() {
private fun initContacts() { private fun initContacts() {
ContactsHelper(this).getContacts { ContactsHelper(this).getContacts {
if (isDestroyed) { if (isDestroyed || isFinishing) {
return@getContacts return@getContacts
} }

@ -39,7 +39,6 @@ class SettingsActivity : SimpleActivity() {
setupShowPhoneNumbers() setupShowPhoneNumbers()
setupShowContactsWithNumbers() setupShowContactsWithNumbers()
setupStartNameWithSurname() setupStartNameWithSurname()
setupFilterDuplicates()
setupShowCallConfirmation() setupShowCallConfirmation()
setupShowDialpadButton() setupShowDialpadButton()
setupShowDialpadLetters() setupShowDialpadLetters()
@ -130,14 +129,6 @@ class SettingsActivity : SimpleActivity() {
} }
} }
private fun setupFilterDuplicates() {
settings_filter_duplicates.isChecked = config.filterDuplicates
settings_filter_duplicates_holder.setOnClickListener {
settings_filter_duplicates.toggle()
config.filterDuplicates = settings_filter_duplicates.isChecked
}
}
private fun setupShowDialpadButton() { private fun setupShowDialpadButton() {
settings_show_dialpad_button.isChecked = config.showDialpadButton settings_show_dialpad_button.isChecked = config.showDialpadButton
settings_show_dialpad_button_holder.setOnClickListener { settings_show_dialpad_button_holder.setOnClickListener {

@ -9,6 +9,7 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.RelativeLayout import android.widget.RelativeLayout
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS
import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.helpers.ensureBackgroundThread
@ -16,10 +17,12 @@ import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.dialogs.CallConfirmationDialog import com.simplemobiletools.contacts.pro.dialogs.CallConfirmationDialog
import com.simplemobiletools.contacts.pro.extensions.* import com.simplemobiletools.contacts.pro.extensions.*
import com.simplemobiletools.contacts.pro.helpers.* import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.models.*
import kotlinx.android.synthetic.main.activity_view_contact.* import kotlinx.android.synthetic.main.activity_view_contact.*
import kotlinx.android.synthetic.main.item_event.view.*
import kotlinx.android.synthetic.main.item_view_address.view.* import kotlinx.android.synthetic.main.item_view_address.view.*
import kotlinx.android.synthetic.main.item_view_contact_source.view.*
import kotlinx.android.synthetic.main.item_view_email.view.* import kotlinx.android.synthetic.main.item_view_email.view.*
import kotlinx.android.synthetic.main.item_view_event.view.*
import kotlinx.android.synthetic.main.item_view_group.view.* import kotlinx.android.synthetic.main.item_view_group.view.*
import kotlinx.android.synthetic.main.item_view_im.view.* import kotlinx.android.synthetic.main.item_view_im.view.*
import kotlinx.android.synthetic.main.item_view_phone_number.view.* import kotlinx.android.synthetic.main.item_view_phone_number.view.*
@ -28,7 +31,12 @@ import kotlinx.android.synthetic.main.item_website.view.*
class ViewContactActivity : ContactActivity() { class ViewContactActivity : ContactActivity() {
private var isViewIntent = false private var isViewIntent = false
private var wasEditLaunched = false private var wasEditLaunched = false
private var duplicateContacts = ArrayList<Contact>()
private var contactSources = ArrayList<ContactSource>()
private var showFields = 0 private var showFields = 0
private var fullContact: Contact? = null // contact with all fields filled from duplicates
private val COMPARABLE_PHONE_NUMBER_LENGTH = 7
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -77,10 +85,10 @@ class ViewContactActivity : ContactActivity() {
} }
when (item.itemId) { when (item.itemId) {
R.id.edit -> editContact() R.id.edit -> launchEditContact(contact!!)
R.id.share -> shareContact() R.id.share -> shareContact(fullContact!!)
R.id.open_with -> openWith() R.id.open_with -> openWith()
R.id.delete -> deleteContact() R.id.delete -> deleteContactFromAllSources()
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
return true return true
@ -96,6 +104,7 @@ class ViewContactActivity : ContactActivity() {
val lookupKey = getLookupKeyFromUri(data) val lookupKey = getLookupKeyFromUri(data)
if (lookupKey != null) { if (lookupKey != null) {
contact = ContactsHelper(this).getContactWithLookupKey(lookupKey) contact = ContactsHelper(this).getContactWithLookupKey(lookupKey)
fullContact = contact
wasLookupKeyUsed = true wasLookupKeyUsed = true
} }
@ -112,6 +121,8 @@ class ViewContactActivity : ContactActivity() {
if (contactId != 0 && !wasLookupKeyUsed) { if (contactId != 0 && !wasLookupKeyUsed) {
contact = ContactsHelper(this).getContactWithId(contactId, intent.getBooleanExtra(IS_PRIVATE, false)) contact = ContactsHelper(this).getContactWithId(contactId, intent.getBooleanExtra(IS_PRIVATE, false))
fullContact = contact
if (contact == null) { if (contact == null) {
if (!wasEditLaunched) { if (!wasEditLaunched) {
toast(R.string.unknown_error_occurred) toast(R.string.unknown_error_occurred)
@ -191,21 +202,28 @@ class ViewContactActivity : ContactActivity() {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
setupFavorite() setupFavorite()
setupNames() setupNames()
setupPhoneNumbers()
setupEmails() ContactsHelper(this).getContactSources {
setupAddresses() contactSources = it
setupIMs() getDuplicateContacts {
setupEvents() setupPhoneNumbers()
setupNotes() setupEmails()
setupOrganization() setupAddresses()
setupWebsites() setupIMs()
setupGroups() setupEvents()
setupContactSource() setupWebsites()
setupGroups()
setupContactSources()
setupNotes()
setupOrganization()
updateTextColors(contact_scrollview)
}
}
} }
private fun editContact() { private fun launchEditContact(contact: Contact) {
wasEditLaunched = true wasEditLaunched = true
editContact(contact!!) editContact(contact)
} }
private fun openWith() { private fun openWith() {
@ -267,8 +285,23 @@ class ViewContactActivity : ContactActivity() {
} }
private fun setupPhoneNumbers() { private fun setupPhoneNumbers() {
var phoneNumbers = contact!!.phoneNumbers.toMutableSet() as LinkedHashSet<PhoneNumber>
duplicateContacts.forEach {
phoneNumbers.addAll(it.phoneNumbers)
}
phoneNumbers = phoneNumbers.distinctBy {
if (it.normalizedNumber != null && it.normalizedNumber!!.length >= COMPARABLE_PHONE_NUMBER_LENGTH) {
it.normalizedNumber?.substring(it.normalizedNumber!!.length - COMPARABLE_PHONE_NUMBER_LENGTH)
} else {
it.normalizedNumber
}
}.toMutableSet() as LinkedHashSet<PhoneNumber>
phoneNumbers = phoneNumbers.sortedBy { it.type }.toMutableSet() as LinkedHashSet<PhoneNumber>
fullContact!!.phoneNumbers = phoneNumbers.toMutableList() as ArrayList<PhoneNumber>
contact_numbers_holder.removeAllViews() contact_numbers_holder.removeAllViews()
val phoneNumbers = contact!!.phoneNumbers
if (phoneNumbers.isNotEmpty() && showFields and SHOW_PHONE_NUMBERS_FIELD != 0) { if (phoneNumbers.isNotEmpty() && showFields and SHOW_PHONE_NUMBERS_FIELD != 0) {
phoneNumbers.forEach { phoneNumbers.forEach {
layoutInflater.inflate(R.layout.item_view_phone_number, contact_numbers_holder, false).apply { layoutInflater.inflate(R.layout.item_view_phone_number, contact_numbers_holder, false).apply {
@ -297,6 +330,7 @@ class ViewContactActivity : ContactActivity() {
} }
} }
// a contact cannot have different emails per contact source. Such contacts are handled as separate ones, not duplicates of each other
private fun setupEmails() { private fun setupEmails() {
contact_emails_holder.removeAllViews() contact_emails_holder.removeAllViews()
val emails = contact!!.emails val emails = contact!!.emails
@ -323,8 +357,15 @@ class ViewContactActivity : ContactActivity() {
} }
private fun setupAddresses() { private fun setupAddresses() {
var addresses = contact!!.addresses.toMutableSet() as LinkedHashSet<Address>
duplicateContacts.forEach {
addresses.addAll(it.addresses)
}
addresses = addresses.sortedBy { it.type }.toMutableSet() as LinkedHashSet<Address>
fullContact!!.addresses = addresses.toMutableList() as ArrayList<Address>
contact_addresses_holder.removeAllViews() contact_addresses_holder.removeAllViews()
val addresses = contact!!.addresses
if (addresses.isNotEmpty() && showFields and SHOW_ADDRESSES_FIELD != 0) { if (addresses.isNotEmpty() && showFields and SHOW_ADDRESSES_FIELD != 0) {
addresses.forEach { addresses.forEach {
layoutInflater.inflate(R.layout.item_view_address, contact_addresses_holder, false).apply { layoutInflater.inflate(R.layout.item_view_address, contact_addresses_holder, false).apply {
@ -348,8 +389,15 @@ class ViewContactActivity : ContactActivity() {
} }
private fun setupIMs() { private fun setupIMs() {
var IMs = contact!!.IMs.toMutableSet() as LinkedHashSet<IM>
duplicateContacts.forEach {
IMs.addAll(it.IMs)
}
IMs = IMs.sortedBy { it.type }.toMutableSet() as LinkedHashSet<IM>
fullContact!!.IMs = IMs.toMutableList() as ArrayList<IM>
contact_ims_holder.removeAllViews() contact_ims_holder.removeAllViews()
val IMs = contact!!.IMs
if (IMs.isNotEmpty() && showFields and SHOW_IMS_FIELD != 0) { if (IMs.isNotEmpty() && showFields and SHOW_IMS_FIELD != 0) {
IMs.forEach { IMs.forEach {
layoutInflater.inflate(R.layout.item_view_im, contact_ims_holder, false).apply { layoutInflater.inflate(R.layout.item_view_im, contact_ims_holder, false).apply {
@ -369,16 +417,21 @@ class ViewContactActivity : ContactActivity() {
} }
private fun setupEvents() { private fun setupEvents() {
var events = contact!!.events.toMutableSet() as LinkedHashSet<Event>
duplicateContacts.forEach {
events.addAll(it.events)
}
events = events.sortedBy { it.type }.toMutableSet() as LinkedHashSet<Event>
fullContact!!.events = events.toMutableList() as ArrayList<Event>
contact_events_holder.removeAllViews() contact_events_holder.removeAllViews()
val events = contact!!.events
if (events.isNotEmpty() && showFields and SHOW_EVENTS_FIELD != 0) { if (events.isNotEmpty() && showFields and SHOW_EVENTS_FIELD != 0) {
events.forEach { events.forEach {
layoutInflater.inflate(R.layout.item_event, contact_events_holder, false).apply { layoutInflater.inflate(R.layout.item_view_event, contact_events_holder, false).apply {
contact_events_holder.addView(this) contact_events_holder.addView(this)
contact_event.alpha = 1f
it.value.getDateTimeFromDateString(contact_event) it.value.getDateTimeFromDateString(contact_event)
contact_event_type.setText(getEventTextId(it.type)) contact_event_type.setText(getEventTextId(it.type))
contact_event_remove.beGone()
copyOnLongClick(it.value) copyOnLongClick(it.value)
} }
} }
@ -390,6 +443,97 @@ class ViewContactActivity : ContactActivity() {
} }
} }
private fun setupWebsites() {
var websites = contact!!.websites.toMutableSet() as LinkedHashSet<String>
duplicateContacts.forEach {
websites.addAll(it.websites)
}
websites = websites.sorted().toMutableSet() as LinkedHashSet<String>
fullContact!!.websites = websites.toMutableList() as ArrayList<String>
contact_websites_holder.removeAllViews()
if (websites.isNotEmpty() && showFields and SHOW_WEBSITES_FIELD != 0) {
websites.forEach {
val url = it
layoutInflater.inflate(R.layout.item_website, contact_websites_holder, false).apply {
contact_websites_holder.addView(this)
contact_website.text = url
copyOnLongClick(url)
setOnClickListener {
openWebsiteIntent(url)
}
}
}
contact_websites_image.beVisible()
contact_websites_holder.beVisible()
} else {
contact_websites_image.beGone()
contact_websites_holder.beGone()
}
}
private fun setupGroups() {
var groups = contact!!.groups.toMutableSet() as LinkedHashSet<Group>
duplicateContacts.forEach {
groups.addAll(it.groups)
}
groups = groups.sortedBy { it.title }.toMutableSet() as LinkedHashSet<Group>
fullContact!!.groups = groups.toMutableList() as ArrayList<Group>
contact_groups_holder.removeAllViews()
if (groups.isNotEmpty() && showFields and SHOW_GROUPS_FIELD != 0) {
groups.forEach {
layoutInflater.inflate(R.layout.item_view_group, contact_groups_holder, false).apply {
val group = it
contact_groups_holder.addView(this)
contact_group.text = group.title
copyOnLongClick(group.title)
}
}
contact_groups_image.beVisible()
contact_groups_holder.beVisible()
} else {
contact_groups_image.beGone()
contact_groups_holder.beGone()
}
}
private fun setupContactSources() {
contact_sources_holder.removeAllViews()
if (showFields and SHOW_CONTACT_SOURCE_FIELD != 0) {
var sources = HashMap<Contact, String>()
sources[contact!!] = getPublicContactSourceSync(contact!!.source, contactSources)
duplicateContacts.forEach {
sources[it] = getPublicContactSourceSync(it.source, contactSources)
}
if (sources.size > 1) {
sources = sources.toList().sortedBy { (key, value) -> value.toLowerCase() }.toMap() as LinkedHashMap<Contact, String>
}
for ((key, value) in sources) {
layoutInflater.inflate(R.layout.item_view_contact_source, contact_sources_holder, false).apply {
contact_source.text = value
contact_source.copyOnLongClick(value)
contact_sources_holder.addView(this)
contact_source.setOnClickListener {
launchEditContact(key)
}
}
}
contact_source_image.beVisible()
contact_sources_holder.beVisible()
} else {
contact_source_image.beGone()
contact_sources_holder.beGone()
}
}
private fun setupNotes() { private fun setupNotes() {
val notes = contact!!.notes val notes = contact!!.notes
if (notes.isNotEmpty() && showFields and SHOW_NOTES_FIELD != 0) { if (notes.isNotEmpty() && showFields and SHOW_NOTES_FIELD != 0) {
@ -424,61 +568,38 @@ class ViewContactActivity : ContactActivity() {
} }
} }
private fun setupWebsites() { private fun getDuplicateContacts(callback: () -> Unit) {
contact_websites_holder.removeAllViews() ContactsHelper(this).getDuplicatesOfContact(contact!!, false) { contacts ->
val websites = contact!!.websites ensureBackgroundThread {
if (websites.isNotEmpty() && showFields and SHOW_WEBSITES_FIELD != 0) { duplicateContacts.clear()
websites.forEach { contacts.forEach {
val url = it val duplicate = ContactsHelper(this).getContactWithId(it.id, it.isPrivate())
layoutInflater.inflate(R.layout.item_website, contact_websites_holder, false).apply { if (duplicate != null) {
contact_websites_holder.addView(this) duplicateContacts.add(duplicate)
contact_website.text = url
copyOnLongClick(url)
setOnClickListener {
openWebsiteIntent(url)
} }
} }
}
contact_websites_image.beVisible()
contact_websites_holder.beVisible()
} else {
contact_websites_image.beGone()
contact_websites_holder.beGone()
}
}
private fun setupGroups() { runOnUiThread {
contact_groups_holder.removeAllViews() callback()
val groups = contact!!.groups
if (groups.isNotEmpty() && showFields and SHOW_GROUPS_FIELD != 0) {
groups.forEach {
layoutInflater.inflate(R.layout.item_view_group, contact_groups_holder, false).apply {
val group = it
contact_groups_holder.addView(this)
contact_group.text = group.title
copyOnLongClick(group.title)
} }
} }
contact_groups_image.beVisible()
contact_groups_holder.beVisible()
} else {
contact_groups_image.beGone()
contact_groups_holder.beGone()
} }
} }
private fun setupContactSource() { private fun deleteContactFromAllSources() {
if (showFields and SHOW_CONTACT_SOURCE_FIELD != 0) { val addition = if (contact_sources_holder.childCount > 1) {
getPublicContactSource(contact!!.source) { "\n\n${getString(R.string.delete_from_all_sources)}"
contact_source.text = it
contact_source.copyOnLongClick(it)
}
contact_source_image.beVisible()
contact_source.beVisible()
} else { } else {
contact_source_image.beGone() ""
contact_source.beGone() }
val message = "${getString(R.string.proceed_with_deletion)}$addition"
ConfirmationDialog(this, message) {
if (contact != null) {
ContactsHelper(this).deleteContact(contact!!, true) {
finish()
}
}
} }
} }

@ -176,16 +176,23 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList<Cont
val positions = getSelectedItemPositions() val positions = getSelectedItemPositions()
contactItems.removeAll(contactsToRemove) contactItems.removeAll(contactsToRemove)
ensureBackgroundThread { ContactsHelper(activity).getContacts(true) { allContacts ->
ContactsHelper(activity).deleteContacts(contactsToRemove) ensureBackgroundThread {
contactsToRemove.forEach {
val contactToRemove = it
val duplicates = allContacts.filter { it.id != contactToRemove.id && it.getHashToCompare() == contactToRemove.getHashToCompare() }.toMutableList() as ArrayList<Contact>
duplicates.add(contactToRemove)
ContactsHelper(activity).deleteContacts(duplicates)
}
activity.runOnUiThread { activity.runOnUiThread {
if (contactItems.isEmpty()) { if (contactItems.isEmpty()) {
refreshListener?.refreshContacts(ALL_TABS_MASK) refreshListener?.refreshContacts(ALL_TABS_MASK)
finishActMode() finishActMode()
} else { } else {
removeSelectedItems(positions) removeSelectedItems(positions)
refreshListener?.refreshContacts(CONTACTS_TAB_MASK or FAVORITES_TAB_MASK) refreshListener?.refreshContacts(CONTACTS_TAB_MASK or FAVORITES_TAB_MASK)
}
} }
} }
} }
@ -265,7 +272,7 @@ class ContactsAdapter(activity: SimpleActivity, var contactItems: ArrayList<Cont
override fun onViewRecycled(holder: ViewHolder) { override fun onViewRecycled(holder: ViewHolder) {
super.onViewRecycled(holder) super.onViewRecycled(holder)
if (!activity.isDestroyed) { if (!activity.isDestroyed && !activity.isFinishing) {
Glide.with(activity).clear(holder.itemView.contact_tmb) Glide.with(activity).clear(holder.itemView.contact_tmb)
} }
} }

@ -117,7 +117,7 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Con
.error(contactDrawable) .error(contactDrawable)
.centerCrop() .centerCrop()
if (activity.isDestroyed) { if (!activity.isDestroyed && !activity.isFinishing) {
Glide.with(activity).load(contact.photoUri).transition(DrawableTransitionOptions.withCrossFade()).apply(options).into(contact_tmb) Glide.with(activity).load(contact.photoUri).transition(DrawableTransitionOptions.withCrossFade()).apply(options).into(contact_tmb)
} }
} else { } else {
@ -136,7 +136,7 @@ class SelectContactsAdapter(val activity: SimpleActivity, val contacts: List<Con
override fun onViewRecycled(holder: ViewHolder) { override fun onViewRecycled(holder: ViewHolder) {
super.onViewRecycled(holder) super.onViewRecycled(holder)
if (!activity.isDestroyed) { if (!activity.isDestroyed && !activity.isFinishing) {
Glide.with(activity).clear(holder.itemView.contact_tmb) Glide.with(activity).clear(holder.itemView.contact_tmb)
} }
} }

@ -85,7 +85,6 @@ fun SimpleActivity.showContactSourcePicker(currentSource: String, callback: (new
} }
} }
fun BaseSimpleActivity.shareContacts(contacts: ArrayList<Contact>) { fun BaseSimpleActivity.shareContacts(contacts: ArrayList<Contact>) {
val file = getTempFile() val file = getTempFile()
if (file == null) { if (file == null) {

@ -15,7 +15,10 @@ import android.provider.ContactsContract
import android.telecom.TelecomManager import android.telecom.TelecomManager
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.PERMISSION_READ_CONTACTS
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CONTACTS
import com.simplemobiletools.commons.helpers.isMarshmallowPlus
import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.contacts.pro.BuildConfig import com.simplemobiletools.contacts.pro.BuildConfig
import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.EditContactActivity import com.simplemobiletools.contacts.pro.activities.EditContactActivity
@ -30,7 +33,6 @@ import com.simplemobiletools.contacts.pro.models.ContactSource
import com.simplemobiletools.contacts.pro.models.Organization import com.simplemobiletools.contacts.pro.models.Organization
import java.io.File import java.io.File
val Context.config: Config get() = Config.newInstance(applicationContext) val Context.config: Config get() = Config.newInstance(applicationContext)
val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao() val Context.contactsDB: ContactsDao get() = ContactsDatabase.getInstance(applicationContext).ContactsDao()
@ -196,24 +198,39 @@ fun Context.getPublicContactSource(source: String, callback: (String) -> Unit) {
when (source) { when (source) {
SMT_PRIVATE -> callback(getString(R.string.phone_storage_hidden)) SMT_PRIVATE -> callback(getString(R.string.phone_storage_hidden))
else -> { else -> {
ensureBackgroundThread { ContactsHelper(this).getContactSources {
ContactsHelper(this).getContactSources { var newSource = source
var newSource = source for (contactSource in it) {
for (contactSource in it) { if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) {
if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) { newSource += " (${getString(R.string.telegram)})"
newSource += " (${getString(R.string.telegram)})" break
break
}
}
Handler(Looper.getMainLooper()).post {
callback(newSource)
} }
} }
Handler(Looper.getMainLooper()).post {
callback(newSource)
}
} }
} }
} }
} }
fun Context.getPublicContactSourceSync(source: String, contactSources: ArrayList<ContactSource>): String {
return when (source) {
SMT_PRIVATE -> getString(R.string.phone_storage_hidden)
else -> {
var newSource = source
for (contactSource in contactSources) {
if (contactSource.name == source && contactSource.type == TELEGRAM_PACKAGE) {
newSource += " (${getString(R.string.telegram)})"
break
}
}
return newSource
}
}
}
fun Context.sendSMSToContacts(contacts: ArrayList<Contact>) { fun Context.sendSMSToContacts(contacts: ArrayList<Contact>) {
val numbers = StringBuilder() val numbers = StringBuilder()
contacts.forEach { contacts.forEach {

@ -41,10 +41,6 @@ class Config(context: Context) : BaseConfig(context) {
SHOW_ADDRESSES_FIELD or SHOW_EVENTS_FIELD or SHOW_NOTES_FIELD or SHOW_GROUPS_FIELD or SHOW_CONTACT_SOURCE_FIELD) SHOW_ADDRESSES_FIELD or SHOW_EVENTS_FIELD or SHOW_NOTES_FIELD or SHOW_GROUPS_FIELD or SHOW_CONTACT_SOURCE_FIELD)
set(showContactFields) = prefs.edit().putInt(SHOW_CONTACT_FIELDS, showContactFields).apply() set(showContactFields) = prefs.edit().putInt(SHOW_CONTACT_FIELDS, showContactFields).apply()
var filterDuplicates: Boolean
get() = prefs.getBoolean(FILTER_DUPLICATES, true)
set(filterDuplicates) = prefs.edit().putBoolean(FILTER_DUPLICATES, filterDuplicates).apply()
var showTabs: Int var showTabs: Int
get() = prefs.getInt(SHOW_TABS, ALL_TABS_MASK) get() = prefs.getInt(SHOW_TABS, ALL_TABS_MASK)
set(showTabs) = prefs.edit().putInt(SHOW_TABS, showTabs).apply() set(showTabs) = prefs.edit().putInt(SHOW_TABS, showTabs).apply()

@ -13,7 +13,6 @@ const val LAST_USED_CONTACT_SOURCE = "last_used_contact_source"
const val ON_CONTACT_CLICK = "on_contact_click" const val ON_CONTACT_CLICK = "on_contact_click"
const val SHOW_CONTACT_FIELDS = "show_contact_fields" const val SHOW_CONTACT_FIELDS = "show_contact_fields"
const val SHOW_TABS = "show_tabs" const val SHOW_TABS = "show_tabs"
const val FILTER_DUPLICATES = "filter_duplicates"
const val SHOW_CALL_CONFIRMATION = "show_call_confirmation" const val SHOW_CALL_CONFIRMATION = "show_call_confirmation"
const val SHOW_DIALPAD_BUTTON = "show_dialpad_button" const val SHOW_DIALPAD_BUTTON = "show_dialpad_button"
const val SHOW_DIALPAD_LETTERS = "show_dialpad_letters" const val SHOW_DIALPAD_LETTERS = "show_dialpad_letters"

@ -28,18 +28,18 @@ class ContactsHelper(val context: Context) {
private val BATCH_SIZE = 50 private val BATCH_SIZE = 50
private var displayContactSources = ArrayList<String>() private var displayContactSources = ArrayList<String>()
fun getContacts(isExporting: Boolean = false, ignoredContactSources: HashSet<String> = HashSet(), callback: (ArrayList<Contact>) -> Unit) { fun getContacts(getAll: Boolean = false, ignoredContactSources: HashSet<String> = HashSet(), callback: (ArrayList<Contact>) -> Unit) {
ensureBackgroundThread { ensureBackgroundThread {
val contacts = SparseArray<Contact>() val contacts = SparseArray<Contact>()
displayContactSources = context.getVisibleContactSources() displayContactSources = context.getVisibleContactSources()
if (isExporting) { if (getAll) {
displayContactSources = if (ignoredContactSources.isEmpty()) { displayContactSources = if (ignoredContactSources.isEmpty()) {
context.getAllContactSources().map { it.getFullIdentifier() }.toMutableList() as ArrayList context.getAllContactSources().map { it.name }.toMutableList() as ArrayList
} else { } else {
context.getAllContactSources().filter { context.getAllContactSources().filter {
it.getFullIdentifier().isNotEmpty() && !ignoredContactSources.contains(it.getFullIdentifier()) it.getFullIdentifier().isNotEmpty() && !ignoredContactSources.contains(it.getFullIdentifier())
}.map { it.getFullIdentifier() }.toMutableList() as ArrayList }.map { it.name }.toMutableList() as ArrayList
} }
} }
@ -66,7 +66,7 @@ class ContactsHelper(val context: Context) {
contacts.valueAt(it) contacts.valueAt(it)
} }
if (ignoredContactSources.isEmpty() && context.config.filterDuplicates && !isExporting) { if (ignoredContactSources.isEmpty() && !getAll) {
tempContacts = tempContacts.distinctBy { tempContacts = tempContacts.distinctBy {
it.getHashToCompare() it.getHashToCompare()
} as ArrayList<Contact> } as ArrayList<Contact>
@ -848,7 +848,7 @@ class ContactsHelper(val context: Context) {
} }
} }
private fun getContactSourcesSync(): ArrayList<ContactSource> { fun getContactSourcesSync(): ArrayList<ContactSource> {
val sources = getDeviceContactSources() val sources = getDeviceContactSources()
sources.add(context.getPrivateContactSource()) sources.add(context.getPrivateContactSource())
return ArrayList(sources) return ArrayList(sources)
@ -1524,21 +1524,29 @@ class ContactsHelper(val context: Context) {
LocalContactsHelper(context).toggleFavorites(localContacts, addToFavorites) LocalContactsHelper(context).toggleFavorites(localContacts, addToFavorites)
} }
fun deleteContact(contact: Contact) { fun deleteContact(originalContact: Contact, deleteClones: Boolean = false, callback: (success: Boolean) -> Unit) {
ensureBackgroundThread { ensureBackgroundThread {
if (contact.isPrivate()) { if (deleteClones) {
context.contactsDB.deleteContactId(contact.id) getDuplicatesOfContact(originalContact, true) { contacts ->
ensureBackgroundThread {
if (deleteContacts(contacts)) {
callback(true)
}
}
}
} else { } else {
deleteContacts(arrayListOf(contact)) if (deleteContacts(arrayListOf(originalContact))) {
callback(true)
}
} }
} }
} }
fun deleteContacts(contacts: ArrayList<Contact>) { fun deleteContacts(contacts: ArrayList<Contact>): Boolean {
val localContacts = contacts.filter { it.isPrivate() }.map { it.id.toLong() }.toMutableList() val localContacts = contacts.filter { it.isPrivate() }.map { it.id.toLong() }.toMutableList()
LocalContactsHelper(context).deleteContactIds(localContacts) LocalContactsHelper(context).deleteContactIds(localContacts)
try { return try {
val operations = ArrayList<ContentProviderOperation>() val operations = ArrayList<ContentProviderOperation>()
val selection = "${ContactsContract.RawContacts._ID} = ?" val selection = "${ContactsContract.RawContacts._ID} = ?"
contacts.filter { !it.isPrivate() }.forEach { contacts.filter { !it.isPrivate() }.forEach {
@ -1557,8 +1565,22 @@ class ContactsHelper(val context: Context) {
if (context.hasPermission(PERMISSION_WRITE_CONTACTS)) { if (context.hasPermission(PERMISSION_WRITE_CONTACTS)) {
context.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations) context.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations)
} }
true
} catch (e: Exception) { } catch (e: Exception) {
context.showErrorToast(e) context.showErrorToast(e)
false
}
}
fun getDuplicatesOfContact(contact: Contact, addOriginal: Boolean, callback: (ArrayList<Contact>) -> Unit) {
ensureBackgroundThread {
getContacts(true) { contacts ->
val duplicates = contacts.filter { it.id != contact.id && it.getHashToCompare() == contact.getHashToCompare() }.toMutableList() as ArrayList<Contact>
if (addOriginal) {
duplicates.add(contact)
}
callback(duplicates)
}
} }
} }
} }

@ -70,7 +70,7 @@ class VcfExporter {
} }
contact.events.forEach { contact.events.forEach {
if (it.type == CommonDataKinds.Event.TYPE_BIRTHDAY || it.type == CommonDataKinds.Event.TYPE_ANNIVERSARY) { if (it.type == CommonDataKinds.Event.TYPE_ANNIVERSARY || it.type == CommonDataKinds.Event.TYPE_BIRTHDAY) {
val dateTime = it.value.getDateTimeFromDateString() val dateTime = it.value.getDateTimeFromDateString()
if (it.value.startsWith("--")) { if (it.value.startsWith("--")) {
val partialDate = PartialDate.builder().year(null).month(dateTime.monthOfYear).date(dateTime.dayOfMonth).build() val partialDate = PartialDate.builder().year(null).month(dateTime.monthOfYear).date(dateTime.dayOfMonth).build()

@ -88,13 +88,13 @@ class VcfImporter(val activity: SimpleActivity) {
} }
val events = ArrayList<Event>() val events = ArrayList<Event>()
ezContact.birthdays.forEach { ezContact.anniversaries.forEach {
val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_BIRTHDAY) val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_ANNIVERSARY)
events.add(event) events.add(event)
} }
ezContact.anniversaries.forEach { ezContact.birthdays.forEach {
val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_ANNIVERSARY) val event = Event(formatDateToDayCode(it.date), CommonDataKinds.Event.TYPE_BIRTHDAY)
events.add(event) events.add(event)
} }

@ -112,7 +112,7 @@ data class Contact(var id: Int, var prefix: String, var firstName: String, var m
emails.mapTo(newEmails) { Email(it.value, 0, "") } emails.mapTo(newEmails) { Email(it.value, 0, "") }
return copy(id = 0, prefix = "", firstName = getNameToDisplay().toLowerCase(), middleName = "", surname = "", suffix = "", nickname = "", photoUri = "", return copy(id = 0, prefix = "", firstName = getNameToDisplay().toLowerCase(), middleName = "", surname = "", suffix = "", nickname = "", photoUri = "",
phoneNumbers = ArrayList(), events = ArrayList(), addresses = ArrayList(), emails = newEmails, starred = 0, contactId = 0, phoneNumbers = ArrayList(), events = ArrayList(), source = "", addresses = ArrayList(), emails = newEmails, starred = 0, contactId = 0,
thumbnailUri = "", notes = "", groups = ArrayList(), websites = ArrayList(), organization = Organization("", ""), IMs = ArrayList()).toString() thumbnailUri = "", notes = "", groups = ArrayList(), websites = ArrayList(), organization = Organization("", ""), IMs = ArrayList()).toString()
} }

@ -244,30 +244,6 @@
</RelativeLayout> </RelativeLayout>
<RelativeLayout
android:id="@+id/settings_filter_duplicates_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/normal_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/normal_margin"
android:paddingBottom="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/settings_filter_duplicates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:paddingStart="@dimen/medium_margin"
android:paddingLeft="@dimen/medium_margin"
android:text="@string/filter_duplicates"
app:switchPadding="@dimen/medium_margin"/>
</RelativeLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/settings_show_call_confirmation_holder" android:id="@+id/settings_show_call_confirmation_holder"
android:layout_width="match_parent" android:layout_width="match_parent"

@ -200,16 +200,8 @@
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin" android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin" android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_phone_vector"/> android:src="@drawable/ic_phone_vector"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_numbers_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_nickname"
android:layout_toEndOf="@+id/contact_numbers_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"/>
<ImageView <ImageView
android:id="@+id/contact_emails_image" android:id="@+id/contact_emails_image"
@ -219,16 +211,8 @@
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin" android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin" android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_email_vector"/> android:src="@drawable/ic_email_vector"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_emails_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_numbers_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"/>
<ImageView <ImageView
android:id="@+id/contact_addresses_image" android:id="@+id/contact_addresses_image"
@ -238,16 +222,8 @@
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin" android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin" android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_place_vector"/> android:src="@drawable/ic_place_vector"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_addresses_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_emails_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"/>
<ImageView <ImageView
android:id="@+id/contact_ims_image" android:id="@+id/contact_ims_image"
@ -257,16 +233,8 @@
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin" android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin" android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_im"/> android:src="@drawable/ic_im"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_ims_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_addresses_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"/>
<ImageView <ImageView
android:id="@+id/contact_events_image" android:id="@+id/contact_events_image"
@ -276,15 +244,8 @@
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin" android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin" android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_cake_vector"/> android:src="@drawable/ic_cake_vector"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_events_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_ims_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"/>
<ImageView <ImageView
android:id="@+id/contact_notes_image" android:id="@+id/contact_notes_image"
@ -294,7 +255,130 @@
android:paddingTop="@dimen/medium_margin" android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin" android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin" android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_label_vector"/> android:src="@drawable/ic_label_vector"
android:visibility="gone" />
<ImageView
android:id="@+id/contact_organization_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_organization_company"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_business_vector"
android:visibility="gone" />
<ImageView
android:id="@+id/contact_websites_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_websites_holder"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_link_vector"
android:visibility="gone" />
<ImageView
android:id="@+id/contact_groups_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_groups_holder"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_group_vector"
android:visibility="gone" />
<ImageView
android:id="@+id/contact_source_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_sources_holder"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_account_box_vector"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_numbers_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_nickname"
android:layout_toEndOf="@+id/contact_numbers_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_emails_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_numbers_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_addresses_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_emails_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_ims_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_addresses_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_events_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_ims_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_websites_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_organization_job_position"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_groups_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_websites_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"
android:visibility="gone" />
<LinearLayout
android:id="@+id/contact_sources_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_groups_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"
android:visibility="gone" />
<com.simplemobiletools.commons.views.MyTextView <com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contact_notes" android:id="@+id/contact_notes"
@ -308,17 +392,8 @@
android:paddingStart="@dimen/small_margin" android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin" android:paddingBottom="@dimen/normal_margin"
android:textSize="@dimen/bigger_text_size"/> android:textSize="@dimen/bigger_text_size"
android:visibility="gone" />
<ImageView
android:id="@+id/contact_organization_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_organization_company"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_business_vector"/>
<com.simplemobiletools.commons.views.MyTextView <com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contact_organization_company" android:id="@+id/contact_organization_company"
@ -332,7 +407,8 @@
android:paddingStart="@dimen/small_margin" android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin" android:paddingBottom="@dimen/normal_margin"
android:textSize="@dimen/bigger_text_size"/> android:textSize="@dimen/bigger_text_size"
android:visibility="gone" />
<com.simplemobiletools.commons.views.MyTextView <com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contact_organization_job_position" android:id="@+id/contact_organization_job_position"
@ -346,71 +422,8 @@
android:paddingStart="@dimen/small_margin" android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin" android:paddingBottom="@dimen/normal_margin"
android:textSize="@dimen/bigger_text_size"/>
<ImageView
android:id="@+id/contact_websites_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_websites_holder"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_link_vector"/>
<LinearLayout
android:id="@+id/contact_websites_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_organization_job_position"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"/>
<ImageView
android:id="@+id/contact_groups_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_groups_holder"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_group_vector"/>
<LinearLayout
android:id="@+id/contact_groups_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_websites_holder"
android:layout_toEndOf="@+id/contact_name_image"
android:orientation="vertical"
android:paddingStart="@dimen/small_margin"/>
<ImageView
android:id="@+id/contact_source_image"
android:layout_width="@dimen/contact_icons_size"
android:layout_height="@dimen/contact_icons_size"
android:layout_alignTop="@+id/contact_source"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:src="@drawable/ic_account_box_vector"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contact_source"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/contact_groups_holder"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/contact_name_image"
android:background="?attr/selectableItemBackground"
android:lines="1"
android:maxLines="1"
android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size" android:textSize="@dimen/bigger_text_size"
tools:text="hello@simplemobiletools.com"/> android:visibility="gone" />
</RelativeLayout> </RelativeLayout>
</ScrollView> </ScrollView>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<com.simplemobiletools.commons.views.MyTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contact_source"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"/>

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contact_event_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contact_event"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/contact_event_type"
android:lines="1"
android:maxLines="1"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contact_event_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/contact_event"
android:layout_alignBottom="@+id/contact_event"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:gravity="center"
android:paddingLeft="@dimen/medium_margin"
android:paddingRight="@dimen/medium_margin"
android:text="@string/home"
android:textSize="@dimen/bigger_text_size" />
</RelativeLayout>

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Θέλετε σίγουρα να διαγράψετε %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Θέλετε σίγουρα να διαγράψετε %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">Η επαφή θα καταργηθεί από όλες τις πηγές επαφών.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -96,7 +96,7 @@
<!-- Search --> <!-- Search -->
<string name="search_contacts">Cari kontak</string> <string name="search_contacts">Cari kontak</string>
<string name="search_favorites">Cari favorit</string> <string name="search_favorites">Cari favorit</string>
<string name="search_groups">Search groups</string> <string name="search_groups">Cari grup</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_contacts">Impor kontak</string> <string name="import_contacts">Impor kontak</string>
@ -145,17 +145,18 @@
<string name="blocked_numbers">Nomor yang diblokir</string> <string name="blocked_numbers">Nomor yang diblokir</string>
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Apakah anda yakin ingin menghapus %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">
<item quantity="one">%d contact</item> <item quantity="one">%d kontak</item>
<item quantity="other">%d contacts</item> <item quantity="other">%d kontak</item>
</plurals> </plurals>
<plurals name="delete_groups"> <plurals name="delete_groups">
<item quantity="one">%d group</item> <item quantity="one">%d grup</item>
<item quantity="other">%d groups</item> <item quantity="other">%d grup</item>
</plurals> </plurals>
<!-- FAQ --> <!-- FAQ -->

@ -96,7 +96,7 @@
<!-- Search --> <!-- Search -->
<string name="search_contacts">Cari kontak</string> <string name="search_contacts">Cari kontak</string>
<string name="search_favorites">Cari favorit</string> <string name="search_favorites">Cari favorit</string>
<string name="search_groups">Search groups</string> <string name="search_groups">Cari grup</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_contacts">Impor kontak</string> <string name="import_contacts">Impor kontak</string>
@ -145,17 +145,18 @@
<string name="blocked_numbers">Nomor yang diblokir</string> <string name="blocked_numbers">Nomor yang diblokir</string>
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Apakah anda yakin ingin menghapus %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">
<item quantity="one">%d contact</item> <item quantity="one">%d kontak</item>
<item quantity="other">%d contacts</item> <item quantity="other">%d kontak</item>
</plurals> </plurals>
<plurals name="delete_groups"> <plurals name="delete_groups">
<item quantity="one">%d group</item> <item quantity="one">%d grup</item>
<item quantity="other">%d groups</item> <item quantity="other">%d grup</item>
</plurals> </plurals>
<!-- FAQ --> <!-- FAQ -->

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">%s verwijderen?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">%s verwijderen?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">De contactpersoon zal worden verwijderd uit alle accounts.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -14,7 +14,7 @@
<string name="send_sms_to_group">Enviar SMS para o grupo</string> <string name="send_sms_to_group">Enviar SMS para o grupo</string>
<string name="send_email_to_group">Enviar e-mail para o grupo</string> <string name="send_email_to_group">Enviar e-mail para o grupo</string>
<string name="call_person">Ligar a %s</string> <string name="call_person">Ligar a %s</string>
<string name="request_the_required_permissions">Pedir a permissão necessária</string> <string name="request_the_required_permissions">Pedir permissão necessária</string>
<string name="create_new_contact">Criar novo contacto</string> <string name="create_new_contact">Criar novo contacto</string>
<string name="add_to_existing_contact">Adicionar a contacto existente</string> <string name="add_to_existing_contact">Adicionar a contacto existente</string>
<string name="must_make_default_dialer">Tem que tornar esta a aplicação padrão para poder bloquear números.</string> <string name="must_make_default_dialer">Tem que tornar esta a aplicação padrão para poder bloquear números.</string>
@ -96,7 +96,7 @@
<!-- Search --> <!-- Search -->
<string name="search_contacts">Pesquisar nos contactos</string> <string name="search_contacts">Pesquisar nos contactos</string>
<string name="search_favorites">Pesquisar nos favoritos</string> <string name="search_favorites">Pesquisar nos favoritos</string>
<string name="search_groups">Search groups</string> <string name="search_groups">Pesquisar nos grupos</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_contacts">Importar contactos</string> <string name="import_contacts">Importar contactos</string>
@ -145,17 +145,18 @@
<string name="blocked_numbers">Números bloqueados</string> <string name="blocked_numbers">Números bloqueados</string>
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Tem a certeza de que deseja apagar %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">
<item quantity="one">%d contact</item> <item quantity="one">%d contacto</item>
<item quantity="other">%d contacts</item> <item quantity="other">%d contactos</item>
</plurals> </plurals>
<plurals name="delete_groups"> <plurals name="delete_groups">
<item quantity="one">%d group</item> <item quantity="one">%d grupo</item>
<item quantity="other">%d groups</item> <item quantity="other">%d grupos</item>
</plurals> </plurals>
<!-- FAQ --> <!-- FAQ -->

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Вы уверены, что хотите удалить %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Вы уверены, что хотите удалить %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Ste si istý, že chcete vymazať %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Ste si istý, že chcete vymazať %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">Kontakt bude vymazaný zo všetkých zdrojov kontaktov.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">

@ -145,17 +145,18 @@
<string name="blocked_numbers">黑名單</string> <string name="blocked_numbers">黑名單</string>
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">你確認要刪除 %s 嗎?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">
<item quantity="one">%d contact</item> <item quantity="one">%d個聯絡人</item>
<item quantity="other">%d contacts</item> <item quantity="other">%d個聯絡人</item>
</plurals> </plurals>
<plurals name="delete_groups"> <plurals name="delete_groups">
<item quantity="one">%d group</item> <item quantity="one">%d個群組</item>
<item quantity="other">%d groups</item> <item quantity="other">%d個群組</item>
</plurals> </plurals>
<!-- FAQ --> <!-- FAQ -->

@ -14,6 +14,7 @@
<string name="telegram">Telegram</string> <string name="telegram">Telegram</string>
<!-- Release notes --> <!-- Release notes -->
<string name="release_47">Removed the setting for merging duplicate contacts, merge them always</string>
<string name="release_40"> <string name="release_40">
Removed the Recents tab due to Googles\' latest security policies being stricter than initiall thought\n Removed the Recents tab due to Googles\' latest security policies being stricter than initiall thought\n
Allow showing letters on the dialpad Allow showing letters on the dialpad

@ -146,6 +146,7 @@
<!-- Confirmation dialog --> <!-- Confirmation dialog -->
<string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? --> <string name="delete_contacts_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 contacts? -->
<string name="delete_from_all_sources">The contact will be removed from all contact sources.</string>
<!-- Are you sure you want to delete 5 contacts? --> <!-- Are you sure you want to delete 5 contacts? -->
<plurals name="delete_contacts"> <plurals name="delete_contacts">