From d9213ed2397bee93827562abd332f358d4929007 Mon Sep 17 00:00:00 2001 From: Dharanish Date: Sat, 13 Jul 2024 15:44:27 +0200 Subject: [PATCH] Implement option to remove sub habits from groups --- .../habits/edit/EditHabitActivity.kt | 2 +- .../habits/list/ListHabitsSelectionMenu.kt | 7 ++++ .../habits/list/views/HabitCardView.kt | 1 - .../main/res/menu/list_habits_selection.xml | 5 +++ .../src/main/res/values/strings.xml | 1 + .../core/commands/DeleteHabitsCommand.kt | 2 +- .../commands/RefreshParentGroupCommand.kt | 2 +- .../core/commands/RemoveFromGroupCommand.kt | 38 +++++++++++++++++++ .../org/isoron/uhabits/core/models/Habit.kt | 4 +- .../models/memory/MemoryHabitGroupList.kt | 2 +- .../screens/habits/list/ListHabitsBehavior.kt | 8 ++-- .../list/ListHabitsSelectionMenuBehavior.kt | 12 ++++++ 12 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RemoveFromGroupCommand.kt diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/edit/EditHabitActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/edit/EditHabitActivity.kt index ee3adc30b..950e8edae 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/edit/EditHabitActivity.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/edit/EditHabitActivity.kt @@ -300,7 +300,7 @@ class EditHabitActivity : AppCompatActivity() { habit.unit = binding.unitInput.text.trim().toString() } habit.type = habitType - habit.parent = parentGroup + habit.group = parentGroup habit.groupId = parentGroup?.id habit.groupUUID = parentGroup?.uuid diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsSelectionMenu.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsSelectionMenu.kt index bf54b3ce6..ddd9a3b58 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsSelectionMenu.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsSelectionMenu.kt @@ -75,12 +75,14 @@ class ListHabitsSelectionMenu @Inject constructor( val itemColor = menu.findItem(R.id.action_color) val itemArchive = menu.findItem(R.id.action_archive_habit) val itemUnarchive = menu.findItem(R.id.action_unarchive_habit) + val itemRemoveFromGroup = menu.findItem(R.id.action_remove_from_group) val itemNotify = menu.findItem(R.id.action_notify) itemColor.isVisible = true itemEdit.isVisible = behavior.canEdit() itemArchive.isVisible = behavior.canArchive() itemUnarchive.isVisible = behavior.canUnarchive() + itemRemoveFromGroup.isVisible = behavior.areSubHabits() itemNotify.isVisible = prefs.isDeveloper activeActionMode?.title = (listAdapter.selectedHabits.size + listAdapter.selectedHabitGroups.size).toString() return true @@ -106,6 +108,11 @@ class ListHabitsSelectionMenu @Inject constructor( return true } + R.id.action_remove_from_group -> { + behavior.onRemoveFromGroup() + return true + } + R.id.action_delete -> { behavior.onDeleteHabits() return true diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt index 649829b3a..e047549b9 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt @@ -97,7 +97,6 @@ class HabitCardView( set(value) { scoreRing.setPercentage(value.toFloat()) scoreRing.setPrecision(1.0f / 16) -// behavior.onChangeScore(habit!!) } var unit diff --git a/uhabits-android/src/main/res/menu/list_habits_selection.xml b/uhabits-android/src/main/res/menu/list_habits_selection.xml index 57ac32bf5..4a3a986b5 100644 --- a/uhabits-android/src/main/res/menu/list_habits_selection.xml +++ b/uhabits-android/src/main/res/menu/list_habits_selection.xml @@ -41,6 +41,11 @@ android:title="@string/unarchive" app:showAsAction="never"/> + + Delete Archive Unarchive + Remove from group Add habit Change color Habit created diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/DeleteHabitsCommand.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/DeleteHabitsCommand.kt index 25a41feab..26321c29e 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/DeleteHabitsCommand.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/DeleteHabitsCommand.kt @@ -31,7 +31,7 @@ data class DeleteHabitsCommand( if (!h.isSubHabit()) { habitList.remove(h) } else { - val list = (h.parent as HabitGroup).habitList + val list = (h.group as HabitGroup).habitList list.remove(h) } } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RefreshParentGroupCommand.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RefreshParentGroupCommand.kt index 70322c3c0..13662abea 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RefreshParentGroupCommand.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RefreshParentGroupCommand.kt @@ -27,7 +27,7 @@ data class RefreshParentGroupCommand( ) : Command { override fun run() { if (!habit.isSubHabit()) return - val hgr = habit.parent + val hgr = habit.group hgr!!.recompute() habitGroupList.resort() } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RemoveFromGroupCommand.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RemoveFromGroupCommand.kt new file mode 100644 index 000000000..80e5c6d1e --- /dev/null +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/commands/RemoveFromGroupCommand.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016-2021 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package org.isoron.uhabits.core.commands + +import org.isoron.uhabits.core.models.Habit +import org.isoron.uhabits.core.models.HabitList + +data class RemoveFromGroupCommand( + val habitList: HabitList, + val selected: List +) : Command { + override fun run() { + for (habit in selected) { + val hgr = habit.group!! + hgr.habitList.remove(habit) + habit.groupId = null + habit.group = null + habit.groupUUID = null + habitList.add(habit) + } + } +} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Habit.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Habit.kt index 470d75765..8a0c1a17c 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Habit.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/Habit.kt @@ -47,7 +47,7 @@ data class Habit( if (uuid == null) this.uuid = UUID.randomUUID().toString().replace("-", "") } - var parent: HabitGroup? = null + var group: HabitGroup? = null var observable = ModelObservable() val isNumerical: Boolean @@ -128,7 +128,7 @@ data class Habit( this.type = other.type this.unit = other.unit this.uuid = other.uuid - this.parent = other.parent + this.group = other.group this.groupId = other.groupId this.groupUUID = other.groupUUID } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt index 732119513..b9aa7a71e 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt @@ -190,7 +190,7 @@ class MemoryHabitGroupList : HabitGroupList { override fun attachHabitsToGroups() { for (hgr in list) { for (h in hgr.habitList) { - h.parent = hgr + h.group = hgr } } } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt index 03d33fc12..97e5742b4 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt @@ -60,7 +60,7 @@ open class ListHabitsBehavior @Inject constructor( } fun onEdit(habit: Habit, timestamp: Timestamp?) { - val list = if (habit.isSubHabit()) habit.parent!!.habitList else habitList + val list = if (habit.isSubHabit()) habit.group!!.habitList else habitList val entry = habit.computedEntries.get(timestamp!!) if (habit.type == HabitType.NUMERICAL) { val oldValue = entry.value.toDouble() / 1000 @@ -114,8 +114,8 @@ open class ListHabitsBehavior @Inject constructor( } fun onReorderHabit(from: Habit, to: Habit) { - if (from.parent == to.parent) { - val list = from.parent?.habitList ?: habitList + if (from.group == to.group) { + val list = from.group?.habitList ?: habitList taskRunner.execute { list.reorder(from, to) } } } @@ -148,7 +148,7 @@ open class ListHabitsBehavior @Inject constructor( } fun onToggle(habit: Habit, timestamp: Timestamp, value: Int, notes: String, x: Float, y: Float) { - val list = if (habit.isSubHabit()) habit.parent!!.habitList else habitList + val list = if (habit.isSubHabit()) habit.group!!.habitList else habitList commandRunner.run( CreateRepetitionCommand(list, habit, timestamp, value, notes) ) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsSelectionMenuBehavior.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsSelectionMenuBehavior.kt index 178a193c7..9f81cb487 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsSelectionMenuBehavior.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsSelectionMenuBehavior.kt @@ -26,6 +26,7 @@ import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.commands.DeleteHabitGroupsCommand import org.isoron.uhabits.core.commands.DeleteHabitsCommand import org.isoron.uhabits.core.commands.RefreshParentGroupCommand +import org.isoron.uhabits.core.commands.RemoveFromGroupCommand import org.isoron.uhabits.core.commands.UnarchiveHabitsCommand import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.HabitGroup @@ -59,6 +60,11 @@ class ListHabitsSelectionMenuBehavior @Inject constructor( return true } + fun areSubHabits(): Boolean { + if (adapter.getSelectedHabitGroups().isNotEmpty()) return false + return (adapter.getSelectedHabits().all { it.isSubHabit() }) + } + fun onArchiveHabits() { commandRunner.run(ArchiveHabitsCommand(habitList, adapter.getSelectedHabits())) commandRunner.run(ArchiveHabitGroupsCommand(habitGroupList, adapter.getSelectedHabitGroups())) @@ -130,6 +136,12 @@ class ListHabitsSelectionMenuBehavior @Inject constructor( adapter.clearSelection() } + fun onRemoveFromGroup() { + adapter.performRemove(adapter.getSelectedHabits()) + commandRunner.run(RemoveFromGroupCommand(habitList, adapter.getSelectedHabits())) + adapter.clearSelection() + } + interface Adapter { fun clearSelection() fun getSelectedHabits(): List