Reassign all mappings to chosen group when disabling groups

This commit is contained in:
fgerber 2024-04-08 17:44:49 +02:00
parent 59a72e0544
commit ddef61a0cf
10 changed files with 125 additions and 23 deletions

View File

@ -15,6 +15,7 @@ import net.helcel.beans.countries.GeoLoc
import net.helcel.beans.databinding.ItemListGeolocBinding
import net.helcel.beans.helper.AUTO_GROUP
import net.helcel.beans.helper.Data
import net.helcel.beans.helper.DialogCloser
import net.helcel.beans.helper.NO_GROUP
import net.helcel.beans.helper.Settings
import net.helcel.beans.helper.Theme.colorWrapper
@ -52,7 +53,7 @@ class GeolocListAdapter(
private val _binding: ItemListGeolocBinding,
private val _parentHolder: FoldingListViewHolder? = null,
private val _parentGeoLoc: GeoLoc,
) : RecyclerView.ViewHolder(_binding.root) {
) : RecyclerView.ViewHolder(_binding.root), DialogCloser {
private fun bindGroup(el: GeoLoc) {
refreshCount(el)
@ -86,11 +87,11 @@ class GeolocListAdapter(
if (_binding.checkBox.isChecked) {
// If one has just checked the box (assign unique group)
Data.selected_group = Data.groups.getUniqueEntry()
onColorDialogDismiss(false)
onDialogDismiss(false)
} else {
// If one has just unchecked the box (unassign unique group)
Data.selected_group = null
onColorDialogDismiss(true)
onDialogDismiss(true)
}
} else {
Data.selected_group = null
@ -103,7 +104,7 @@ class GeolocListAdapter(
}
}
fun onColorDialogDismiss(clear: Boolean) {
override fun onDialogDismiss(clear: Boolean) {
if (clear) {
Data.visits.setVisited(Data.selected_geoloc, NO_GROUP)
Data.saveData()

View File

@ -13,7 +13,8 @@ import net.helcel.beans.helper.Theme.getContrastColor
class GroupListAdapter(
private val activity: FragmentActivity,
private val selectDialog: DialogFragment
private val selectDialog: DialogFragment,
private val delete: Boolean = false
) : RecyclerView.Adapter<GroupListAdapter.GroupViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GroupViewHolder {
@ -63,12 +64,14 @@ class GroupListAdapter(
Data.selected_group = entry.second
selectDialog.dismiss()
}
_binding.groupColor.setOnLongClickListener {
dialogFragment.show(
activity.supportFragmentManager,
"AddColorDialogFragment"
)
true
if (!delete) {
_binding.groupColor.setOnLongClickListener {
dialogFragment.show(
activity.supportFragmentManager,
"AddColorDialogFragment"
)
true
}
}
}
}

View File

@ -52,8 +52,8 @@ class EditGroupAddFragment(
.setPositiveButton(android.R.string.ok) { _, _ ->
val pos = Data.groups.findGroupPos(key)
// Remove all countries belonging to that group
// Delete the group
Data.visits.deleteVisited(key)
// Delete the group
Data.groups.deleteGroup(key)
Data.saveData()
onDelCb(pos)

View File

@ -3,17 +3,19 @@ package net.helcel.beans.activity.fragment
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.view.View
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import net.helcel.beans.activity.adapter.GeolocListAdapter
import net.helcel.beans.R
import net.helcel.beans.activity.adapter.GroupListAdapter
import net.helcel.beans.databinding.FragmentEditPlacesColorsBinding
import net.helcel.beans.helper.Data
import net.helcel.beans.helper.DialogCloser
class EditPlaceColorFragment(private val parent: GeolocListAdapter.FoldingListViewHolder) :
class EditPlaceColorFragment(private val parent: DialogCloser, private val delete: Boolean = false) :
DialogFragment() {
private lateinit var _binding: FragmentEditPlacesColorsBinding
@ -21,7 +23,8 @@ class EditPlaceColorFragment(private val parent: GeolocListAdapter.FoldingListVi
private var clear: Boolean = false
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = MaterialAlertDialogBuilder(requireContext())
val ctx = requireContext()
val builder = MaterialAlertDialogBuilder(ctx)
_binding = FragmentEditPlacesColorsBinding.inflate(layoutInflater)
_binding.btnAdd.setOnClickListener {
EditGroupAddFragment(0, {
@ -34,16 +37,25 @@ class EditPlaceColorFragment(private val parent: GeolocListAdapter.FoldingListVi
}
val dialog = builder.setView(_binding.root).create()
listAdapt = GroupListAdapter(requireActivity(), this)
listAdapt = GroupListAdapter(requireActivity(), this, delete)
_binding.groupsColor.layoutManager =
LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
LinearLayoutManager(ctx, RecyclerView.VERTICAL, false)
_binding.groupsColor.adapter = listAdapt
if (delete) {
_binding.btnAdd.visibility = View.GONE
_binding.btnClear.text = ctx.getString(R.string.cancel)
with (_binding.warningText) {
visibility = View.VISIBLE
text = ctx.getString(R.string.select_group)
}
}
return dialog
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
parent.onColorDialogDismiss(clear)
parent.onDialogDismiss(clear)
}
}

View File

@ -1,19 +1,52 @@
package net.helcel.beans.activity.fragment
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import net.helcel.beans.R
import net.helcel.beans.countries.GeoLocImporter
import net.helcel.beans.helper.Data
import net.helcel.beans.helper.DialogCloser
import net.helcel.beans.helper.Settings
class SettingsFragment : PreferenceFragmentCompat() {
class SettingsFragment : PreferenceFragmentCompat(), DialogCloser {
private var savedInstanceState: Bundle? = null
private var rootKey: String? = null
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
this.savedInstanceState = savedInstanceState
this.rootKey = rootKey
setPreferencesFromResource(R.xml.fragment_settings, rootKey)
val ctx = requireContext()
// Select Light/Dark/System Mode
findPreference<Preference>(getString(R.string.key_theme))?.setOnPreferenceChangeListener { _, key ->
setTheme(ctx, key as String)
}
// Toggle groups
findPreference<Preference>(getString(R.string.key_group))?.setOnPreferenceChangeListener { _, key ->
if (key as String == ctx.getString(R.string.off)) {
val fragment = EditPlaceColorFragment(this, true)
fragment.show(
this.parentFragmentManager,
"AddColorDialogFragment"
)
false
} else {
true
}
}
// Toggle regional geolocs
findPreference<Preference>(getString(R.string.key_regional))?.setOnPreferenceChangeListener { _, key ->
when (key as String) {
ctx.getString(R.string.off) -> GeoLocImporter.clearStates()
@ -22,10 +55,6 @@ class SettingsFragment : PreferenceFragmentCompat() {
true
}
// Select Light/Dark/System Mode
findPreference<Preference>(getString(R.string.key_theme))?.setOnPreferenceChangeListener { _, key ->
setTheme(ctx, key as String)
}
// Open license fragment
findPreference<Preference>(getString(R.string.licenses))?.setOnPreferenceClickListener {
@ -58,4 +87,30 @@ class SettingsFragment : PreferenceFragmentCompat() {
return true
}
}
override fun onDialogDismiss(clear: Boolean) {
// When turning groups off, select one group to keep and reassign everything
Data.selected_group?.let { selectedGroup ->
// Reassign all visited that are not to selectedGroup to selectedGroup
Data.visits.reassignAllVisitedtoGroup(selectedGroup.key)
// Delete all groups that are not selectedGroup
Data.groups.deleteAllExcept(selectedGroup.key)
// Save and clear global variables
Data.saveData()
Data.selected_geoloc = null
Data.selected_group = null
// Actually change preference
val ctx = requireContext()
val sp = PreferenceManager.getDefaultSharedPreferences(ctx)
sp.edit().putString(ctx.getString(R.string.key_group), ctx.getString(R.string.off))
.commit()
// Refresh entire preference fragment to reflect changes
preferenceScreen.removeAll()
onCreatePreferences(savedInstanceState, rootKey)
}
}
}

View File

@ -0,0 +1,5 @@
package net.helcel.beans.helper
interface DialogCloser {
fun onDialogDismiss(clear: Boolean)
}

View File

@ -28,6 +28,11 @@ class Groups(val id: Int, private val grps: HashMap<Int, Group>) {
grps.remove(key)
}
fun deleteAllExcept(grp: Int) {
val keysToDelete = grps.keys.filter { it != grp }
keysToDelete.forEach { grps.remove(it) }
}
fun getGroupFromKey(key: Int): Group {
return grps.getOrDefault(key, EmptyGroup())
}
@ -60,6 +65,10 @@ class Groups(val id: Int, private val grps: HashMap<Int, Group>) {
return grps.keys.toList().indexOf(key)
}
fun forEach(action: (Map.Entry<Int, Group>) -> Unit) {
grps.forEach { action(it) }
}
class EmptyGroup : Group(0, "")
@Serializable

View File

@ -42,6 +42,15 @@ class Visits(val id: Int, private val locs: HashMap<String, Int>) {
return locs.keys.groupBy { getVisited(it) }
}
fun reassignAllVisitedtoGroup(group: Int) {
val keys = locs.filter { (_, grp) ->
grp !in listOf(NO_GROUP, AUTO_GROUP)
}.keys
keys.forEach {
locs[it] = group
}
}
@OptIn(ExperimentalSerializationApi::class)
@Serializer(Visits::class)
class VisitsSerializer {

View File

@ -6,6 +6,13 @@
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/warning_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:visibility="gone" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -21,6 +21,7 @@
<string name="foss_licenses">Free and open source dependencies and licenses</string>
<string name="about_beans">About the Beans application</string>
<string name="delete_group">Are your sure you want to delete this group and remove all its country mappings?</string>
<string name="select_group">Select one group you want to keep. All others will be deleted and its mappings reassigned to the group you choose here.</string>
<string name="add">Add</string>
<string name="clear">Clear</string>
<string name="logo">Logo</string>