mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Allow user to sort by status (#660)
This commit is contained in:
@@ -104,6 +104,11 @@ class ListHabitsMenu @Inject constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.actionSortStatus -> {
|
||||||
|
behavior.onSortByStatus()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ package org.isoron.uhabits.activities.habits.list.views;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.widget.*;
|
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -83,7 +83,8 @@ public class HabitCardListAdapter
|
|||||||
cache.setListener(this);
|
cache.setListener(this);
|
||||||
cache.setCheckmarkCount(
|
cache.setCheckmarkCount(
|
||||||
ListHabitsRootViewKt.MAX_CHECKMARK_COUNT);
|
ListHabitsRootViewKt.MAX_CHECKMARK_COUNT);
|
||||||
cache.setOrder(preferences.getDefaultOrder());
|
cache.setSecondaryOrder(preferences.getDefaultSecondaryOrder());
|
||||||
|
cache.setPrimaryOrder(preferences.getDefaultPrimaryOrder());
|
||||||
|
|
||||||
setHasStableIds(true);
|
setHasStableIds(true);
|
||||||
}
|
}
|
||||||
@@ -160,7 +161,7 @@ public class HabitCardListAdapter
|
|||||||
|
|
||||||
public boolean isSortable()
|
public boolean isSortable()
|
||||||
{
|
{
|
||||||
return cache.getOrder() == HabitList.Order.BY_POSITION;
|
return cache.getPrimaryOrder() == HabitList.Order.BY_POSITION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -313,16 +314,22 @@ public class HabitCardListAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOrder(HabitList.Order order)
|
public void setPrimaryOrder(HabitList.Order order)
|
||||||
{
|
{
|
||||||
cache.setOrder(order);
|
cache.setPrimaryOrder(order);
|
||||||
preferences.setDefaultOrder(order);
|
preferences.setDefaultPrimaryOrder(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HabitList.Order getOrder()
|
public void setSecondaryOrder(HabitList.Order order) {
|
||||||
|
cache.setSecondaryOrder(order);
|
||||||
|
preferences.setDefaultSecondaryOrder(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HabitList.Order getPrimaryOrder()
|
||||||
{
|
{
|
||||||
return cache.getOrder();
|
return cache.getPrimaryOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -65,6 +65,10 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/actionSortScore"
|
android:id="@+id/actionSortScore"
|
||||||
android:title="@string/by_score"/>
|
android:title="@string/by_score"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/actionSortStatus"
|
||||||
|
android:title="@string/by_status"/>
|
||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
</menu>
|
</menu>
|
||||||
|
|||||||
@@ -159,6 +159,7 @@
|
|||||||
<string name="by_name">By name</string>
|
<string name="by_name">By name</string>
|
||||||
<string name="by_color">By color</string>
|
<string name="by_color">By color</string>
|
||||||
<string name="by_score">By score</string>
|
<string name="by_score">By score</string>
|
||||||
|
<string name="by_status">By status</string>
|
||||||
<string name="export">Export</string>
|
<string name="export">Export</string>
|
||||||
<string name="long_press_to_edit">Press-and-hold to change the value</string>
|
<string name="long_press_to_edit">Press-and-hold to change the value</string>
|
||||||
<string name="change_value">Change value</string>
|
<string name="change_value">Change value</string>
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ import static org.isoron.uhabits.core.utils.StringUtils.defaultToStringStyle;
|
|||||||
* While repetitions simply record that the habit was performed at a given date,
|
* While repetitions simply record that the habit was performed at a given date,
|
||||||
* a checkmark provides more information, such as whether a repetition was
|
* a checkmark provides more information, such as whether a repetition was
|
||||||
* expected at that day or not.
|
* expected at that day or not.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Note that the status comparator in
|
||||||
|
* {@link org.isoron.uhabits.core.models.memory.MemoryHabitList}
|
||||||
|
* relies on SKIP > YES_MANUAL > YES_AUTO > NO.
|
||||||
* <p>
|
* <p>
|
||||||
* Checkmarks are computed automatically from the list of repetitions.
|
* Checkmarks are computed automatically from the list of repetitions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -107,14 +107,23 @@ public abstract class HabitList implements Iterable<Habit>
|
|||||||
return observable;
|
return observable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Order getOrder();
|
public abstract Order getPrimaryOrder();
|
||||||
|
|
||||||
|
public abstract Order getSecondaryOrder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the order of the elements on the list.
|
* Changes the order of the elements on the list.
|
||||||
*
|
*
|
||||||
* @param order the new order criterea
|
* @param order the new order criterion
|
||||||
*/
|
*/
|
||||||
public abstract void setOrder(@NonNull Order order);
|
public abstract void setPrimaryOrder(@NonNull Order order);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the previous order of the elements on the list.
|
||||||
|
*
|
||||||
|
* @param order the new order criterion
|
||||||
|
*/
|
||||||
|
public abstract void setSecondaryOrder(@NonNull Order order);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the given habit in the list, or -1 if the list does
|
* Returns the index of the given habit in the list, or -1 if the list does
|
||||||
@@ -242,6 +251,8 @@ public abstract class HabitList implements Iterable<Habit>
|
|||||||
csv.close();
|
csv.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public enum Order
|
public enum Order
|
||||||
{
|
{
|
||||||
BY_NAME_ASC,
|
BY_NAME_ASC,
|
||||||
@@ -250,6 +261,8 @@ public abstract class HabitList implements Iterable<Habit>
|
|||||||
BY_COLOR_DESC,
|
BY_COLOR_DESC,
|
||||||
BY_SCORE_ASC,
|
BY_SCORE_ASC,
|
||||||
BY_SCORE_DESC,
|
BY_SCORE_DESC,
|
||||||
|
BY_STATUS_ASC,
|
||||||
|
BY_STATUS_DESC,
|
||||||
BY_POSITION
|
BY_POSITION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,10 +35,13 @@ public class MemoryHabitList extends HabitList
|
|||||||
@NonNull
|
@NonNull
|
||||||
private LinkedList<Habit> list = new LinkedList<>();
|
private LinkedList<Habit> list = new LinkedList<>();
|
||||||
|
|
||||||
private Comparator<Habit> comparator = null;
|
@NonNull
|
||||||
|
private Order primaryOrder = Order.BY_POSITION;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private Order order = Order.BY_POSITION;
|
private Order secondaryOrder = Order.BY_NAME_ASC;
|
||||||
|
|
||||||
|
private Comparator<Habit> comparator = getComposedComparatorByOrder(primaryOrder, secondaryOrder);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private MemoryHabitList parent = null;
|
private MemoryHabitList parent = null;
|
||||||
@@ -55,7 +58,8 @@ public class MemoryHabitList extends HabitList
|
|||||||
super(matcher);
|
super(matcher);
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.comparator = comparator;
|
this.comparator = comparator;
|
||||||
this.order = parent.order;
|
this.primaryOrder = parent.primaryOrder;
|
||||||
|
this.secondaryOrder = parent.secondaryOrder;
|
||||||
parent.getObservable().addListener(this::loadFromParent);
|
parent.getObservable().addListener(this::loadFromParent);
|
||||||
loadFromParent();
|
loadFromParent();
|
||||||
}
|
}
|
||||||
@@ -105,58 +109,88 @@ public class MemoryHabitList extends HabitList
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Order getOrder()
|
public synchronized Order getPrimaryOrder()
|
||||||
{
|
{
|
||||||
return order;
|
return primaryOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setOrder(@NonNull Order order)
|
public synchronized Order getSecondaryOrder()
|
||||||
{
|
{
|
||||||
this.order = order;
|
return secondaryOrder;
|
||||||
this.comparator = getComparatorByOrder(order);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void setPrimaryOrder(@NonNull Order order)
|
||||||
|
{
|
||||||
|
this.primaryOrder = order;
|
||||||
|
this.comparator = getComposedComparatorByOrder(this.primaryOrder, this.secondaryOrder);
|
||||||
resort();
|
resort();
|
||||||
getObservable().notifyListeners();
|
getObservable().notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Comparator<Habit> getComparatorByOrder(Order order)
|
@Override
|
||||||
|
public void setSecondaryOrder(@NonNull Order order)
|
||||||
{
|
{
|
||||||
Comparator<Habit> nameComparatorAsc =
|
this.secondaryOrder = order;
|
||||||
(h1, h2) -> h1.getName().compareTo(h2.getName());
|
this.comparator = getComposedComparatorByOrder(this.primaryOrder, this.secondaryOrder);
|
||||||
|
resort();
|
||||||
|
getObservable().notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
Comparator<Habit> nameComparatorDesc =
|
private Comparator<Habit> getComposedComparatorByOrder(Order firstOrder, Order secondOrder)
|
||||||
(h1, h2) -> nameComparatorAsc.compare(h2, h1);
|
{
|
||||||
|
return (h1, h2) -> {
|
||||||
|
int firstResult = getComparatorByOrder(firstOrder).compare(h1, h2);
|
||||||
|
|
||||||
|
if (firstResult != 0 || secondOrder == null) {
|
||||||
|
return firstResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getComparatorByOrder(secondOrder).compare(h1, h2);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Comparator<Habit> getComparatorByOrder(Order order) {
|
||||||
|
Comparator<Habit> nameComparatorAsc = (h1, h2) ->
|
||||||
|
h1.getName().compareTo(h2.getName());
|
||||||
|
|
||||||
|
Comparator<Habit> nameComparatorDesc = (h1, h2) ->
|
||||||
|
nameComparatorAsc.compare(h2, h1);
|
||||||
|
|
||||||
Comparator<Habit> colorComparatorAsc = (h1, h2) ->
|
Comparator<Habit> colorComparatorAsc = (h1, h2) ->
|
||||||
{
|
h1.getColor().compareTo(h2.getColor());
|
||||||
Integer c1 = h1.getColor();
|
|
||||||
Integer c2 = h2.getColor();
|
|
||||||
if (c1.equals(c2)) return nameComparatorAsc.compare(h1, h2);
|
|
||||||
else return c1.compareTo(c2);
|
|
||||||
};
|
|
||||||
|
|
||||||
Comparator<Habit> colorComparatorDesc =
|
Comparator<Habit> colorComparatorDesc = (h1, h2) ->
|
||||||
(h1, h2) -> colorComparatorAsc.compare(h2, h1);
|
colorComparatorAsc.compare(h2, h1);
|
||||||
|
|
||||||
Comparator<Habit> scoreComparatorDesc = (h1, h2) ->
|
Comparator<Habit> scoreComparatorDesc = (h1, h2) ->
|
||||||
{
|
Double.compare(h1.getScores().getTodayValue(), h2.getScores().getTodayValue());
|
||||||
Double s1 = h1.getScores().getTodayValue();
|
|
||||||
Double s2 = h2.getScores().getTodayValue();
|
|
||||||
if (s1.equals(s2)) return nameComparatorAsc.compare(h1, h2);
|
|
||||||
else return s2.compareTo(s1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Comparator<Habit> scoreComparatorAsc =
|
Comparator<Habit> scoreComparatorAsc = (h1, h2) ->
|
||||||
(h1, h2) -> scoreComparatorDesc.compare(h2, h1);
|
scoreComparatorDesc.compare(h2, h1);
|
||||||
|
|
||||||
Comparator<Habit> positionComparator = (h1, h2) ->
|
Comparator<Habit> positionComparator = (h1, h2) ->
|
||||||
|
h1.getPosition().compareTo(h2.getPosition());
|
||||||
|
|
||||||
|
Comparator<Habit> statusComparatorDesc = (h1, h2) ->
|
||||||
{
|
{
|
||||||
Integer p1 = h1.getPosition();
|
if (h1.isCompletedToday() != h2.isCompletedToday()) {
|
||||||
Integer p2 = h2.getPosition();
|
return h1.isCompletedToday() ? -1 : 1;
|
||||||
if (p1.equals(p2)) return nameComparatorAsc.compare(h1, h2);
|
}
|
||||||
else return p1.compareTo(p2);
|
|
||||||
|
if (h1.isNumerical() != h2.isNumerical()) {
|
||||||
|
return h1.isNumerical() ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer v1 = Objects.requireNonNull(h1.getCheckmarks().getToday()).getValue();
|
||||||
|
Integer v2 = Objects.requireNonNull(h2.getCheckmarks().getToday()).getValue();
|
||||||
|
|
||||||
|
return v2.compareTo(v1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Comparator<Habit> statusComparatorAsc = (h1, h2) -> statusComparatorDesc.compare(h2, h1);
|
||||||
|
|
||||||
if (order == BY_POSITION) return positionComparator;
|
if (order == BY_POSITION) return positionComparator;
|
||||||
if (order == BY_NAME_ASC) return nameComparatorAsc;
|
if (order == BY_NAME_ASC) return nameComparatorAsc;
|
||||||
if (order == BY_NAME_DESC) return nameComparatorDesc;
|
if (order == BY_NAME_DESC) return nameComparatorDesc;
|
||||||
@@ -164,6 +198,8 @@ public class MemoryHabitList extends HabitList
|
|||||||
if (order == BY_COLOR_DESC) return colorComparatorDesc;
|
if (order == BY_COLOR_DESC) return colorComparatorDesc;
|
||||||
if (order == BY_SCORE_DESC) return scoreComparatorDesc;
|
if (order == BY_SCORE_DESC) return scoreComparatorDesc;
|
||||||
if (order == BY_SCORE_ASC) return scoreComparatorAsc;
|
if (order == BY_SCORE_ASC) return scoreComparatorAsc;
|
||||||
|
if (order == BY_STATUS_DESC) return statusComparatorDesc;
|
||||||
|
if (order == BY_STATUS_ASC) return statusComparatorAsc;
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +228,7 @@ public class MemoryHabitList extends HabitList
|
|||||||
public synchronized void reorder(@NonNull Habit from, @NonNull Habit to)
|
public synchronized void reorder(@NonNull Habit from, @NonNull Habit to)
|
||||||
{
|
{
|
||||||
throwIfHasParent();
|
throwIfHasParent();
|
||||||
if (order != BY_POSITION) throw new IllegalStateException(
|
if (primaryOrder != BY_POSITION) throw new IllegalStateException(
|
||||||
"cannot reorder automatically sorted list");
|
"cannot reorder automatically sorted list");
|
||||||
|
|
||||||
if (indexOf(from) < 0) throw new IllegalArgumentException(
|
if (indexOf(from) < 0) throw new IllegalArgumentException(
|
||||||
|
|||||||
@@ -116,15 +116,28 @@ public class SQLiteHabitList extends HabitList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
public Order getOrder()
|
public Order getPrimaryOrder()
|
||||||
{
|
{
|
||||||
return list.getOrder();
|
return list.getPrimaryOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setOrder(@NonNull Order order)
|
public Order getSecondaryOrder()
|
||||||
{
|
{
|
||||||
list.setOrder(order);
|
return list.getSecondaryOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void setPrimaryOrder(@NonNull Order order)
|
||||||
|
{
|
||||||
|
list.setPrimaryOrder(order);
|
||||||
|
getObservable().notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void setSecondaryOrder(@NonNull Order order)
|
||||||
|
{
|
||||||
|
list.setSecondaryOrder(order);
|
||||||
getObservable().notifyListeners();
|
getObservable().notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class Preferences
|
|||||||
fallbackColor);
|
fallbackColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HabitList.Order getDefaultOrder()
|
public HabitList.Order getDefaultPrimaryOrder()
|
||||||
{
|
{
|
||||||
String name = storage.getString("pref_default_order", "BY_POSITION");
|
String name = storage.getString("pref_default_order", "BY_POSITION");
|
||||||
|
|
||||||
@@ -70,16 +70,35 @@ public class Preferences
|
|||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
setDefaultOrder(HabitList.Order.BY_POSITION);
|
setDefaultPrimaryOrder(HabitList.Order.BY_POSITION);
|
||||||
return HabitList.Order.BY_POSITION;
|
return HabitList.Order.BY_POSITION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultOrder(HabitList.Order order)
|
public HabitList.Order getDefaultSecondaryOrder() {
|
||||||
|
String name = storage.getString("pref_default_secondary_order", "BY_NAME_ASC");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return HabitList.Order.valueOf(name);
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e)
|
||||||
|
{
|
||||||
|
setDefaultSecondaryOrder(HabitList.Order.BY_NAME_ASC);
|
||||||
|
return HabitList.Order.BY_POSITION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultPrimaryOrder(HabitList.Order order)
|
||||||
{
|
{
|
||||||
storage.putString("pref_default_order", order.name());
|
storage.putString("pref_default_order", order.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDefaultSecondaryOrder(HabitList.Order order)
|
||||||
|
{
|
||||||
|
storage.putString("pref_default_secondary_order", order.name());
|
||||||
|
}
|
||||||
|
|
||||||
public int getDefaultScoreSpinnerPosition()
|
public int getDefaultScoreSpinnerPosition()
|
||||||
{
|
{
|
||||||
int defaultScoreInterval =
|
int defaultScoreInterval =
|
||||||
|
|||||||
@@ -116,9 +116,14 @@ public class HabitCardListCache implements CommandRunner.Listener
|
|||||||
return data.habits.size();
|
return data.habits.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized HabitList.Order getOrder()
|
public synchronized HabitList.Order getPrimaryOrder()
|
||||||
{
|
{
|
||||||
return filteredHabits.getOrder();
|
return filteredHabits.getPrimaryOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized HabitList.Order getSecondaryOrder()
|
||||||
|
{
|
||||||
|
return filteredHabits.getSecondaryOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized double getScore(long habitId)
|
public synchronized double getScore(long habitId)
|
||||||
@@ -196,14 +201,22 @@ public class HabitCardListCache implements CommandRunner.Listener
|
|||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setOrder(@NonNull HabitList.Order order)
|
public synchronized void setPrimaryOrder(@NonNull HabitList.Order order)
|
||||||
{
|
{
|
||||||
if (order == null) throw new NullPointerException();
|
if (order == null) throw new NullPointerException();
|
||||||
allHabits.setOrder(order);
|
allHabits.setPrimaryOrder(order);
|
||||||
filteredHabits.setOrder(order);
|
filteredHabits.setPrimaryOrder(order);
|
||||||
refreshAllHabits();
|
refreshAllHabits();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void setSecondaryOrder(@NonNull HabitList.Order order)
|
||||||
|
{
|
||||||
|
allHabits.setSecondaryOrder(order);
|
||||||
|
filteredHabits.setSecondaryOrder(order);
|
||||||
|
refreshAllHabits();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface definition for a callback to be invoked when the data on the
|
* Interface definition for a callback to be invoked when the data on the
|
||||||
* cache has been modified.
|
* cache has been modified.
|
||||||
|
|||||||
@@ -95,36 +95,43 @@ public class ListHabitsMenuBehavior
|
|||||||
updateAdapterFilter();
|
updateAdapterFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSortByColor()
|
|
||||||
{
|
|
||||||
if (adapter.getOrder() != HabitList.Order.BY_COLOR_ASC) {
|
|
||||||
adapter.setOrder(HabitList.Order.BY_COLOR_ASC);
|
|
||||||
} else {
|
|
||||||
adapter.setOrder(HabitList.Order.BY_COLOR_DESC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onSortByManually()
|
public void onSortByManually()
|
||||||
{
|
{
|
||||||
adapter.setOrder(HabitList.Order.BY_POSITION);
|
adapter.setPrimaryOrder(HabitList.Order.BY_POSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onSortByColor()
|
||||||
|
{
|
||||||
|
onSortToggleBy(HabitList.Order.BY_COLOR_ASC, HabitList.Order.BY_COLOR_DESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onSortByScore()
|
public void onSortByScore()
|
||||||
{
|
{
|
||||||
if (adapter.getOrder() != HabitList.Order.BY_SCORE_DESC) {
|
onSortToggleBy(HabitList.Order.BY_SCORE_DESC, HabitList.Order.BY_SCORE_ASC);
|
||||||
adapter.setOrder(HabitList.Order.BY_SCORE_DESC);
|
|
||||||
} else {
|
|
||||||
adapter.setOrder(HabitList.Order.BY_SCORE_ASC);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSortByName()
|
public void onSortByName()
|
||||||
{
|
{
|
||||||
if (adapter.getOrder() != HabitList.Order.BY_NAME_ASC) {
|
onSortToggleBy(HabitList.Order.BY_NAME_ASC, HabitList.Order.BY_NAME_DESC);
|
||||||
adapter.setOrder(HabitList.Order.BY_NAME_ASC);
|
}
|
||||||
|
|
||||||
|
public void onSortByStatus()
|
||||||
|
{
|
||||||
|
onSortToggleBy(HabitList.Order.BY_STATUS_ASC, HabitList.Order.BY_STATUS_DESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onSortToggleBy(HabitList.Order defaultOrder, HabitList.Order reversedOrder)
|
||||||
|
{
|
||||||
|
if (adapter.getPrimaryOrder() != defaultOrder) {
|
||||||
|
if (adapter.getPrimaryOrder() != reversedOrder) {
|
||||||
|
adapter.setSecondaryOrder(adapter.getPrimaryOrder());
|
||||||
|
}
|
||||||
|
adapter.setPrimaryOrder(defaultOrder);
|
||||||
} else {
|
} else {
|
||||||
adapter.setOrder(HabitList.Order.BY_NAME_DESC);
|
adapter.setPrimaryOrder(reversedOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onToggleNightMode()
|
public void onToggleNightMode()
|
||||||
@@ -148,9 +155,11 @@ public class ListHabitsMenuBehavior
|
|||||||
|
|
||||||
void setFilter(HabitMatcher build);
|
void setFilter(HabitMatcher build);
|
||||||
|
|
||||||
void setOrder(HabitList.Order order);
|
void setPrimaryOrder(HabitList.Order order);
|
||||||
|
|
||||||
HabitList.Order getOrder();
|
void setSecondaryOrder(HabitList.Order order);
|
||||||
|
|
||||||
|
HabitList.Order getPrimaryOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Screen
|
public interface Screen
|
||||||
|
|||||||
@@ -68,11 +68,11 @@ public class HabitsCSVExporterTest extends BaseUnitTest
|
|||||||
unzip(archive);
|
unzip(archive);
|
||||||
|
|
||||||
assertPathExists("Habits.csv");
|
assertPathExists("Habits.csv");
|
||||||
assertPathExists("001 Wake up early");
|
assertPathExists("001 Meditate/Checkmarks.csv");
|
||||||
assertPathExists("001 Wake up early/Checkmarks.csv");
|
assertPathExists("001 Meditate/Scores.csv");
|
||||||
assertPathExists("001 Wake up early/Scores.csv");
|
assertPathExists("002 Wake up early");
|
||||||
assertPathExists("002 Meditate/Checkmarks.csv");
|
assertPathExists("002 Wake up early/Checkmarks.csv");
|
||||||
assertPathExists("002 Meditate/Scores.csv");
|
assertPathExists("002 Wake up early/Scores.csv");
|
||||||
assertPathExists("Checkmarks.csv");
|
assertPathExists("Checkmarks.csv");
|
||||||
assertPathExists("Scores.csv");
|
assertPathExists("Scores.csv");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class ImportTest extends BaseUnitTest
|
|||||||
|
|
||||||
assertThat(habitList.size(), equalTo(3));
|
assertThat(habitList.size(), equalTo(3));
|
||||||
|
|
||||||
Habit habit = habitList.getByPosition(0);
|
Habit habit = habitList.getByPosition(1);
|
||||||
assertThat(habit.getName(), equalTo("Wake up early"));
|
assertThat(habit.getName(), equalTo("Wake up early"));
|
||||||
assertThat(habit.getFrequency(), equalTo(THREE_TIMES_PER_WEEK));
|
assertThat(habit.getFrequency(), equalTo(THREE_TIMES_PER_WEEK));
|
||||||
assertFalse(habit.hasReminder());
|
assertFalse(habit.hasReminder());
|
||||||
@@ -90,7 +90,7 @@ public class ImportTest extends BaseUnitTest
|
|||||||
assertTrue(containsRepetition(habit, 2016, 1, 28));
|
assertTrue(containsRepetition(habit, 2016, 1, 28));
|
||||||
assertFalse(containsRepetition(habit, 2016, 3, 10));
|
assertFalse(containsRepetition(habit, 2016, 3, 10));
|
||||||
|
|
||||||
habit = habitList.getByPosition(1);
|
habit = habitList.getByPosition(2);
|
||||||
assertThat(habit.getName(), equalTo("brush teeth"));
|
assertThat(habit.getName(), equalTo("brush teeth"));
|
||||||
assertThat(habit.getFrequency(), equalTo(THREE_TIMES_PER_WEEK));
|
assertThat(habit.getFrequency(), equalTo(THREE_TIMES_PER_WEEK));
|
||||||
assertThat(habit.hasReminder(), equalTo(true));
|
assertThat(habit.hasReminder(), equalTo(true));
|
||||||
@@ -109,7 +109,7 @@ public class ImportTest extends BaseUnitTest
|
|||||||
|
|
||||||
assertThat(habitList.size(), equalTo(3));
|
assertThat(habitList.size(), equalTo(3));
|
||||||
|
|
||||||
Habit h = habitList.getByPosition(0);
|
Habit h = habitList.getByPosition(2);
|
||||||
assertThat(h.getName(), equalTo("Vegan"));
|
assertThat(h.getName(), equalTo("Vegan"));
|
||||||
assertTrue(containsRepetition(h, 2016, 1, 24));
|
assertTrue(containsRepetition(h, 2016, 1, 24));
|
||||||
assertTrue(containsRepetition(h, 2016, 2, 5));
|
assertTrue(containsRepetition(h, 2016, 2, 5));
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ public class HabitListTest extends BaseUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testOrdering()
|
public void testOrdering()
|
||||||
{
|
{
|
||||||
HabitList list = modelFactory.buildHabitList();
|
|
||||||
Habit h1 = fixtures.createEmptyHabit();
|
Habit h1 = fixtures.createEmptyHabit();
|
||||||
h1.setName("A Habit");
|
h1.setName("A Habit");
|
||||||
h1.setColor(2);
|
h1.setColor(2);
|
||||||
@@ -132,46 +131,51 @@ public class HabitListTest extends BaseUnitTest
|
|||||||
h4.setColor(1);
|
h4.setColor(1);
|
||||||
h4.setPosition(2);
|
h4.setPosition(2);
|
||||||
|
|
||||||
|
HabitList list = modelFactory.buildHabitList();
|
||||||
|
|
||||||
list.add(h3);
|
list.add(h3);
|
||||||
list.add(h1);
|
list.add(h1);
|
||||||
list.add(h4);
|
list.add(h4);
|
||||||
list.add(h2);
|
list.add(h2);
|
||||||
|
|
||||||
list.setOrder(BY_POSITION);
|
list.setPrimaryOrder(BY_POSITION);
|
||||||
assertThat(list.getByPosition(0), equalTo(h3));
|
assertThat(list.getByPosition(0), equalTo(h3));
|
||||||
assertThat(list.getByPosition(1), equalTo(h1));
|
assertThat(list.getByPosition(1), equalTo(h1));
|
||||||
assertThat(list.getByPosition(2), equalTo(h4));
|
assertThat(list.getByPosition(2), equalTo(h4));
|
||||||
assertThat(list.getByPosition(3), equalTo(h2));
|
assertThat(list.getByPosition(3), equalTo(h2));
|
||||||
|
|
||||||
list.setOrder(BY_NAME_DESC);
|
list.setPrimaryOrder(BY_NAME_DESC);
|
||||||
assertThat(list.getByPosition(0), equalTo(h4));
|
assertThat(list.getByPosition(0), equalTo(h4));
|
||||||
assertThat(list.getByPosition(1), equalTo(h3));
|
assertThat(list.getByPosition(1), equalTo(h3));
|
||||||
assertThat(list.getByPosition(2), equalTo(h2));
|
assertThat(list.getByPosition(2), equalTo(h2));
|
||||||
assertThat(list.getByPosition(3), equalTo(h1));
|
assertThat(list.getByPosition(3), equalTo(h1));
|
||||||
|
|
||||||
list.setOrder(BY_NAME_ASC);
|
list.setPrimaryOrder(BY_NAME_ASC);
|
||||||
assertThat(list.getByPosition(0), equalTo(h1));
|
assertThat(list.getByPosition(0), equalTo(h1));
|
||||||
assertThat(list.getByPosition(1), equalTo(h2));
|
assertThat(list.getByPosition(1), equalTo(h2));
|
||||||
assertThat(list.getByPosition(2), equalTo(h3));
|
assertThat(list.getByPosition(2), equalTo(h3));
|
||||||
assertThat(list.getByPosition(3), equalTo(h4));
|
assertThat(list.getByPosition(3), equalTo(h4));
|
||||||
|
|
||||||
|
list.setPrimaryOrder(BY_NAME_ASC);
|
||||||
list.remove(h1);
|
list.remove(h1);
|
||||||
list.add(h1);
|
list.add(h1);
|
||||||
assertThat(list.getByPosition(0), equalTo(h1));
|
assertThat(list.getByPosition(0), equalTo(h1));
|
||||||
|
|
||||||
list.setOrder(BY_COLOR_ASC);
|
list.setPrimaryOrder(BY_COLOR_ASC);
|
||||||
|
list.setSecondaryOrder(BY_NAME_ASC);
|
||||||
assertThat(list.getByPosition(0), equalTo(h3));
|
assertThat(list.getByPosition(0), equalTo(h3));
|
||||||
assertThat(list.getByPosition(1), equalTo(h4));
|
assertThat(list.getByPosition(1), equalTo(h4));
|
||||||
assertThat(list.getByPosition(2), equalTo(h1));
|
assertThat(list.getByPosition(2), equalTo(h1));
|
||||||
assertThat(list.getByPosition(3), equalTo(h2));
|
assertThat(list.getByPosition(3), equalTo(h2));
|
||||||
|
|
||||||
list.setOrder(BY_COLOR_DESC);
|
list.setPrimaryOrder(BY_COLOR_DESC);
|
||||||
assertThat(list.getByPosition(0), equalTo(h2));
|
list.setSecondaryOrder(BY_NAME_ASC);
|
||||||
assertThat(list.getByPosition(1), equalTo(h1));
|
assertThat(list.getByPosition(0), equalTo(h1));
|
||||||
|
assertThat(list.getByPosition(1), equalTo(h2));
|
||||||
assertThat(list.getByPosition(2), equalTo(h4));
|
assertThat(list.getByPosition(2), equalTo(h4));
|
||||||
assertThat(list.getByPosition(3), equalTo(h3));
|
assertThat(list.getByPosition(3), equalTo(h3));
|
||||||
|
|
||||||
list.setOrder(BY_POSITION);
|
list.setPrimaryOrder(BY_POSITION);
|
||||||
assertThat(list.getByPosition(0), equalTo(h3));
|
assertThat(list.getByPosition(0), equalTo(h3));
|
||||||
assertThat(list.getByPosition(1), equalTo(h1));
|
assertThat(list.getByPosition(1), equalTo(h1));
|
||||||
assertThat(list.getByPosition(2), equalTo(h4));
|
assertThat(list.getByPosition(2), equalTo(h4));
|
||||||
@@ -179,8 +183,7 @@ public class HabitListTest extends BaseUnitTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReorder()
|
public void testReorder() {
|
||||||
{
|
|
||||||
int operations[][] = {
|
int operations[][] = {
|
||||||
{ 5, 2 }, { 3, 7 }, { 4, 4 }, { 8, 3 }
|
{ 5, 2 }, { 3, 7 }, { 4, 4 }, { 8, 3 }
|
||||||
};
|
};
|
||||||
@@ -225,12 +228,12 @@ public class HabitListTest extends BaseUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testOrder_inherit()
|
public void testOrder_inherit()
|
||||||
{
|
{
|
||||||
habitList.setOrder(BY_COLOR_ASC);
|
habitList.setPrimaryOrder(BY_COLOR_ASC);
|
||||||
HabitList filteredList = habitList.getFiltered(new HabitMatcherBuilder()
|
HabitList filteredList = habitList.getFiltered(new HabitMatcherBuilder()
|
||||||
.setArchivedAllowed(false)
|
.setArchivedAllowed(false)
|
||||||
.setCompletedAllowed(false)
|
.setCompletedAllowed(false)
|
||||||
.build());
|
.build());
|
||||||
assertEquals(filteredList.getOrder(), BY_COLOR_ASC);
|
assertEquals(filteredList.getPrimaryOrder(), BY_COLOR_ASC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -306,7 +309,7 @@ public class HabitListTest extends BaseUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testReorder_onSortedList() throws Exception
|
public void testReorder_onSortedList() throws Exception
|
||||||
{
|
{
|
||||||
habitList.setOrder(BY_SCORE_DESC);
|
habitList.setPrimaryOrder(BY_SCORE_DESC);
|
||||||
Habit h1 = habitsArray.get(1);
|
Habit h1 = habitsArray.get(1);
|
||||||
Habit h2 = habitsArray.get(2);
|
Habit h2 = habitsArray.get(2);
|
||||||
thrown.expect(IllegalStateException.class);
|
thrown.expect(IllegalStateException.class);
|
||||||
|
|||||||
@@ -75,13 +75,13 @@ public class PreferencesTest extends BaseUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testDefaultOrder() throws Exception
|
public void testDefaultOrder() throws Exception
|
||||||
{
|
{
|
||||||
assertThat(prefs.getDefaultOrder(), equalTo(HabitList.Order.BY_POSITION));
|
assertThat(prefs.getDefaultPrimaryOrder(), equalTo(HabitList.Order.BY_POSITION));
|
||||||
|
|
||||||
prefs.setDefaultOrder(HabitList.Order.BY_SCORE_DESC);
|
prefs.setDefaultPrimaryOrder(HabitList.Order.BY_SCORE_DESC);
|
||||||
assertThat(prefs.getDefaultOrder(), equalTo(HabitList.Order.BY_SCORE_DESC));
|
assertThat(prefs.getDefaultPrimaryOrder(), equalTo(HabitList.Order.BY_SCORE_DESC));
|
||||||
|
|
||||||
storage.putString("pref_default_order", "BOGUS");
|
storage.putString("pref_default_order", "BOGUS");
|
||||||
assertThat(prefs.getDefaultOrder(), equalTo(HabitList.Order.BY_POSITION));
|
assertThat(prefs.getDefaultPrimaryOrder(), equalTo(HabitList.Order.BY_POSITION));
|
||||||
assertThat(storage.getString("pref_default_order", ""), equalTo("BY_POSITION"));
|
assertThat(storage.getString("pref_default_order", ""), equalTo("BY_POSITION"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ public class ListHabitsMenuBehaviorTest extends BaseUnitTest
|
|||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<HabitList.Order> orderCaptor;
|
private ArgumentCaptor<HabitList.Order> orderCaptor;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<HabitList.Order> secondaryOrderCaptor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws Exception
|
public void setUp() throws Exception
|
||||||
{
|
{
|
||||||
@@ -103,7 +106,7 @@ public class ListHabitsMenuBehaviorTest extends BaseUnitTest
|
|||||||
public void testOnSortByColor()
|
public void testOnSortByColor()
|
||||||
{
|
{
|
||||||
behavior.onSortByColor();
|
behavior.onSortByColor();
|
||||||
verify(adapter).setOrder(orderCaptor.capture());
|
verify(adapter).setPrimaryOrder(orderCaptor.capture());
|
||||||
assertThat(orderCaptor.getValue(), equalTo(BY_COLOR_ASC));
|
assertThat(orderCaptor.getValue(), equalTo(BY_COLOR_ASC));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +114,7 @@ public class ListHabitsMenuBehaviorTest extends BaseUnitTest
|
|||||||
public void testOnSortManually()
|
public void testOnSortManually()
|
||||||
{
|
{
|
||||||
behavior.onSortByManually();
|
behavior.onSortByManually();
|
||||||
verify(adapter).setOrder(orderCaptor.capture());
|
verify(adapter).setPrimaryOrder(orderCaptor.capture());
|
||||||
assertThat(orderCaptor.getValue(), equalTo(BY_POSITION));
|
assertThat(orderCaptor.getValue(), equalTo(BY_POSITION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +122,7 @@ public class ListHabitsMenuBehaviorTest extends BaseUnitTest
|
|||||||
public void testOnSortScore()
|
public void testOnSortScore()
|
||||||
{
|
{
|
||||||
behavior.onSortByScore();
|
behavior.onSortByScore();
|
||||||
verify(adapter).setOrder(orderCaptor.capture());
|
verify(adapter).setPrimaryOrder(orderCaptor.capture());
|
||||||
assertThat(orderCaptor.getValue(), equalTo(BY_SCORE_DESC));
|
assertThat(orderCaptor.getValue(), equalTo(BY_SCORE_DESC));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +130,34 @@ public class ListHabitsMenuBehaviorTest extends BaseUnitTest
|
|||||||
public void testOnSortName()
|
public void testOnSortName()
|
||||||
{
|
{
|
||||||
behavior.onSortByName();
|
behavior.onSortByName();
|
||||||
verify(adapter).setOrder(orderCaptor.capture());
|
verify(adapter).setPrimaryOrder(orderCaptor.capture());
|
||||||
assertThat(orderCaptor.getValue(), equalTo(BY_NAME_ASC));
|
assertThat(orderCaptor.getValue(), equalTo(BY_NAME_ASC));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnSortStatus()
|
||||||
|
{
|
||||||
|
when(adapter.getPrimaryOrder()).thenReturn(BY_NAME_ASC);
|
||||||
|
|
||||||
|
behavior.onSortByStatus();
|
||||||
|
verify(adapter).setPrimaryOrder(orderCaptor.capture());
|
||||||
|
verify(adapter).setSecondaryOrder(secondaryOrderCaptor.capture());
|
||||||
|
assertThat(orderCaptor.getValue(), equalTo(BY_STATUS_ASC));
|
||||||
|
assertThat(secondaryOrderCaptor.getValue(), equalTo(BY_NAME_ASC));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnSortStatusToggle()
|
||||||
|
{
|
||||||
|
when(adapter.getPrimaryOrder()).thenReturn(BY_STATUS_ASC);
|
||||||
|
|
||||||
|
behavior.onSortByStatus();
|
||||||
|
|
||||||
|
verify(adapter).setPrimaryOrder(orderCaptor.capture());
|
||||||
|
verify(adapter, never()).setSecondaryOrder(any());
|
||||||
|
assertThat(orderCaptor.getValue(), equalTo(BY_STATUS_DESC));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnToggleShowArchived()
|
public void testOnToggleShowArchived()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user