Refactor and write documentation for Habit

pull/69/head
Alinson S. Xavier 10 years ago
parent 3d42505fb9
commit 075b7812eb

@ -19,6 +19,7 @@
package org.isoron.uhabits.unit.models; package org.isoron.uhabits.unit.models;
import android.graphics.Color;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
@ -31,6 +32,8 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@ -43,6 +46,49 @@ public class HabitTest
HabitFixtures.purgeHabits(); HabitFixtures.purgeHabits();
} }
@Test
public void constructor_default()
{
Habit habit = new Habit();
assertThat(habit.archived, is(0));
assertThat(habit.highlight, is(0));
assertThat(habit.reminderDays, is(nullValue()));
assertThat(habit.reminderHour, is(nullValue()));
assertThat(habit.reminderMin, is(nullValue()));
assertThat(habit.streaks, is(not(nullValue())));
assertThat(habit.scores, is(not(nullValue())));
assertThat(habit.repetitions, is(not(nullValue())));
assertThat(habit.checkmarks, is(not(nullValue())));
}
@Test
public void constructor_habit()
{
Habit model = new Habit();
model.archived = 1;
model.highlight = 1;
model.color = Color.BLACK;
model.freqNum = 10;
model.freqDen = 20;
model.reminderDays = 1;
model.reminderHour = 8;
model.reminderMin = 30;
model.position = 0;
Habit habit = new Habit(model);
assertThat(habit.archived, is(model.archived));
assertThat(habit.highlight, is(model.highlight));
assertThat(habit.color, is(model.color));
assertThat(habit.freqNum, is(model.freqNum));
assertThat(habit.freqDen, is(model.freqDen));
assertThat(habit.reminderDays, is(model.reminderDays));
assertThat(habit.reminderHour, is(model.reminderHour));
assertThat(habit.reminderMin, is(model.reminderMin));
assertThat(habit.position, is(model.position));
}
@Test @Test
public void reorderTest() public void reorderTest()
{ {

@ -32,6 +32,8 @@ import java.util.TimeZone;
public class DateHelper public class DateHelper
{ {
public static long millisecondsInOneDay = 24 * 60 * 60 * 1000; public static long millisecondsInOneDay = 24 * 60 * 60 * 1000;
public static int ALL_WEEK_DAYS = 127;
private static Long fixedLocalTime = null; private static Long fixedLocalTime = null;
public static long getLocalTime() public static long getLocalTime()

@ -32,6 +32,7 @@ import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import org.isoron.uhabits.BuildConfig; import org.isoron.uhabits.BuildConfig;
import org.isoron.uhabits.commands.Command;
public abstract class DialogHelper public abstract class DialogHelper
{ {

@ -26,6 +26,7 @@ import android.os.Bundle;
import android.widget.Toast; import android.widget.Toast;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.commands.Command;
import java.util.LinkedList; import java.util.LinkedList;

@ -19,7 +19,6 @@
package org.isoron.uhabits.commands; package org.isoron.uhabits.commands;
import org.isoron.helpers.Command;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
@ -45,15 +44,13 @@ public class ArchiveHabitsCommand extends Command
@Override @Override
public void execute() public void execute()
{ {
for(Habit h : habits) Habit.archive(habits);
h.archive();
} }
@Override @Override
public void undo() public void undo()
{ {
for(Habit h : habits) Habit.unarchive(habits);
h.unarchive();
} }
public Integer getExecuteStringId() public Integer getExecuteStringId()

@ -21,7 +21,6 @@ package org.isoron.uhabits.commands;
import com.activeandroid.ActiveAndroid; import com.activeandroid.ActiveAndroid;
import org.isoron.helpers.Command;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
@ -47,22 +46,7 @@ public class ChangeHabitColorCommand extends Command
@Override @Override
public void execute() public void execute()
{ {
ActiveAndroid.beginTransaction(); Habit.setColor(habits, newColor);
try
{
for(Habit h : habits)
{
h.color = newColor;
h.save();
}
ActiveAndroid.setTransactionSuccessful();
}
finally
{
ActiveAndroid.endTransaction();
}
} }
@Override @Override

@ -17,7 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.isoron.helpers; package org.isoron.uhabits.commands;
public abstract class Command public abstract class Command
{ {

@ -0,0 +1,33 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.commands;
public class CommandFailedException extends RuntimeException
{
public CommandFailedException()
{
super();
}
public CommandFailedException(String message)
{
super(message);
}
}

@ -19,7 +19,6 @@
package org.isoron.uhabits.commands; package org.isoron.uhabits.commands;
import org.isoron.helpers.Command;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
@ -51,7 +50,10 @@ public class CreateHabitCommand extends Command
@Override @Override
public void undo() public void undo()
{ {
Habit.get(savedId).delete(); Habit habit = Habit.get(savedId);
if(habit == null) throw new CommandFailedException("Habit not found");
habit.delete();
} }
@Override @Override

@ -19,7 +19,6 @@
package org.isoron.uhabits.commands; package org.isoron.uhabits.commands;
import org.isoron.helpers.Command;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;

@ -19,7 +19,6 @@
package org.isoron.uhabits.commands; package org.isoron.uhabits.commands;
import org.isoron.helpers.Command;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
@ -43,6 +42,8 @@ public class EditHabitCommand extends Command
public void execute() public void execute()
{ {
Habit habit = Habit.get(savedId); Habit habit = Habit.get(savedId);
if(habit == null) throw new CommandFailedException("Habit not found");
habit.copyAttributes(modified); habit.copyAttributes(modified);
habit.save(); habit.save();
if (hasIntervalChanged) if (hasIntervalChanged)
@ -56,6 +57,8 @@ public class EditHabitCommand extends Command
public void undo() public void undo()
{ {
Habit habit = Habit.get(savedId); Habit habit = Habit.get(savedId);
if(habit == null) throw new CommandFailedException("Habit not found");
habit.copyAttributes(original); habit.copyAttributes(original);
habit.save(); habit.save();
if (hasIntervalChanged) if (hasIntervalChanged)

@ -19,7 +19,6 @@
package org.isoron.uhabits.commands; package org.isoron.uhabits.commands;
import org.isoron.helpers.Command;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
public class ToggleRepetitionCommand extends Command public class ToggleRepetitionCommand extends Command

@ -19,7 +19,6 @@
package org.isoron.uhabits.commands; package org.isoron.uhabits.commands;
import org.isoron.helpers.Command;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
@ -45,15 +44,13 @@ public class UnarchiveHabitsCommand extends Command
@Override @Override
public void execute() public void execute()
{ {
for(Habit h : habits) Habit.unarchive(habits);
h.unarchive();
} }
@Override @Override
public void undo() public void undo()
{ {
for(Habit h : habits) Habit.archive(habits);
h.archive();
} }
public Integer getExecuteStringId() public Integer getExecuteStringId()

@ -39,16 +39,17 @@ import com.android.datetimepicker.time.RadialPickerLayout;
import com.android.datetimepicker.time.TimePickerDialog; import com.android.datetimepicker.time.TimePickerDialog;
import org.isoron.helpers.ColorHelper; import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.Command;
import org.isoron.helpers.DateHelper; import org.isoron.helpers.DateHelper;
import org.isoron.helpers.DialogHelper.OnSavedListener; import org.isoron.helpers.DialogHelper.OnSavedListener;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.commands.Command;
import org.isoron.uhabits.commands.CreateHabitCommand; import org.isoron.uhabits.commands.CreateHabitCommand;
import org.isoron.uhabits.commands.EditHabitCommand; import org.isoron.uhabits.commands.EditHabitCommand;
import org.isoron.uhabits.dialogs.WeekdayPickerDialog; import org.isoron.uhabits.dialogs.WeekdayPickerDialog;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
public class EditHabitFragment extends DialogFragment public class EditHabitFragment extends DialogFragment
implements OnClickListener, WeekdayPickerDialog.OnWeekdaysPickedListener, implements OnClickListener, WeekdayPickerDialog.OnWeekdaysPickedListener,
@ -136,7 +137,10 @@ public class EditHabitFragment extends DialogFragment
} }
else if (mode == EDIT_MODE) else if (mode == EDIT_MODE)
{ {
originalHabit = Habit.get((Long) args.get("habitId")); Long habitId = (Long) args.get("habitId");
if(habitId == null) throw new IllegalArgumentException("habitId must be specified");
originalHabit = Habit.get(habitId);
modifiedHabit = new Habit(originalHabit); modifiedHabit = new Habit(originalHabit);
getDialog().setTitle(R.string.edit_habit); getDialog().setTitle(R.string.edit_habit);
@ -178,14 +182,18 @@ public class EditHabitFragment extends DialogFragment
editor.apply(); editor.apply();
} }
@SuppressWarnings("ConstantConditions")
private void updateReminder() private void updateReminder()
{ {
if (modifiedHabit.reminderHour != null) if (modifiedHabit.hasReminder())
{ {
tvReminderTime.setTextColor(Color.BLACK); tvReminderTime.setTextColor(Color.BLACK);
tvReminderTime.setText(DateHelper.formatTime(getActivity(), modifiedHabit.reminderHour, tvReminderTime.setText(DateHelper.formatTime(getActivity(), modifiedHabit.reminderHour,
modifiedHabit.reminderMin)); modifiedHabit.reminderMin));
tvReminderDays.setVisibility(View.VISIBLE); tvReminderDays.setVisibility(View.VISIBLE);
boolean weekdays[] = DateHelper.unpackWeekdayList(modifiedHabit.reminderDays);
tvReminderDays.setText(DateHelper.formatWeekdayList(getActivity(), weekdays));
} }
else else
{ {
@ -193,9 +201,6 @@ public class EditHabitFragment extends DialogFragment
tvReminderTime.setText(R.string.reminder_off); tvReminderTime.setText(R.string.reminder_off);
tvReminderDays.setVisibility(View.GONE); tvReminderDays.setVisibility(View.GONE);
} }
boolean weekdays[] = DateHelper.unpackWeekdayList(modifiedHabit.reminderDays);
tvReminderDays.setText(DateHelper.formatWeekdayList(getActivity(), weekdays));
} }
public void setOnSavedListener(OnSavedListener onSavedListener) public void setOnSavedListener(OnSavedListener onSavedListener)
@ -303,12 +308,13 @@ public class EditHabitFragment extends DialogFragment
return valid; return valid;
} }
@SuppressWarnings("ConstantConditions")
private void onDateSpinnerClick() private void onDateSpinnerClick()
{ {
int defaultHour = 8; int defaultHour = 8;
int defaultMin = 0; int defaultMin = 0;
if (modifiedHabit.reminderHour != null) if (modifiedHabit.hasReminder())
{ {
defaultHour = modifiedHabit.reminderHour; defaultHour = modifiedHabit.reminderHour;
defaultMin = modifiedHabit.reminderMin; defaultMin = modifiedHabit.reminderMin;
@ -319,8 +325,11 @@ public class EditHabitFragment extends DialogFragment
timePicker.show(getFragmentManager(), "timePicker"); timePicker.show(getFragmentManager(), "timePicker");
} }
@SuppressWarnings("ConstantConditions")
private void onWeekdayClick() private void onWeekdayClick()
{ {
if(!modifiedHabit.hasReminder()) return;
WeekdayPickerDialog dialog = new WeekdayPickerDialog(); WeekdayPickerDialog dialog = new WeekdayPickerDialog();
dialog.setListener(this); dialog.setListener(this);
dialog.setSelectedDays(DateHelper.unpackWeekdayList(modifiedHabit.reminderDays)); dialog.setSelectedDays(DateHelper.unpackWeekdayList(modifiedHabit.reminderDays));
@ -332,14 +341,14 @@ public class EditHabitFragment extends DialogFragment
{ {
modifiedHabit.reminderHour = hour; modifiedHabit.reminderHour = hour;
modifiedHabit.reminderMin = minute; modifiedHabit.reminderMin = minute;
modifiedHabit.reminderDays = DateHelper.ALL_WEEK_DAYS;
updateReminder(); updateReminder();
} }
@Override @Override
public void onTimeCleared(RadialPickerLayout view) public void onTimeCleared(RadialPickerLayout view)
{ {
modifiedHabit.reminderHour = null; modifiedHabit.clearReminder();
modifiedHabit.reminderMin = null;
updateReminder(); updateReminder();
} }
@ -357,12 +366,14 @@ public class EditHabitFragment extends DialogFragment
} }
@Override @Override
@SuppressWarnings("ConstantConditions")
public void onSaveInstanceState(Bundle outState) public void onSaveInstanceState(Bundle outState)
{ {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putInt("color", modifiedHabit.color); outState.putInt("color", modifiedHabit.color);
if(modifiedHabit.reminderHour != null)
if(modifiedHabit.hasReminder())
{ {
outState.putInt("reminderMin", modifiedHabit.reminderMin); outState.putInt("reminderMin", modifiedHabit.reminderMin);
outState.putInt("reminderHour", modifiedHabit.reminderHour); outState.putInt("reminderHour", modifiedHabit.reminderHour);

@ -46,7 +46,7 @@ import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView; import com.mobeta.android.dslv.DragSortListView;
import com.mobeta.android.dslv.DragSortListView.DropListener; import com.mobeta.android.dslv.DragSortListView.DropListener;
import org.isoron.helpers.Command; import org.isoron.uhabits.commands.Command;
import org.isoron.helpers.DateHelper; import org.isoron.helpers.DateHelper;
import org.isoron.helpers.DialogHelper; import org.isoron.helpers.DialogHelper;
import org.isoron.helpers.DialogHelper.OnSavedListener; import org.isoron.helpers.DialogHelper.OnSavedListener;

@ -33,7 +33,7 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.isoron.helpers.ColorHelper; import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.Command; import org.isoron.uhabits.commands.Command;
import org.isoron.helpers.DialogHelper; import org.isoron.helpers.DialogHelper;
import org.isoron.uhabits.HabitBroadcastReceiver; import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;

@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import org.isoron.helpers.DateHelper; import org.isoron.helpers.DateHelper;
@ -43,13 +44,17 @@ public class ReminderHelper
createReminderAlarm(context, habit, null); createReminderAlarm(context, habit, null);
} }
public static void createReminderAlarm(Context context, Habit habit, Long reminderTime) public static void createReminderAlarm(Context context, Habit habit, @Nullable Long reminderTime)
{ {
if(!habit.hasReminder()) return;
if (reminderTime == null) if (reminderTime == null)
{ {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis()); calendar.setTimeInMillis(System.currentTimeMillis());
//noinspection ConstantConditions
calendar.set(Calendar.HOUR_OF_DAY, habit.reminderHour); calendar.set(Calendar.HOUR_OF_DAY, habit.reminderHour);
//noinspection ConstantConditions
calendar.set(Calendar.MINUTE, habit.reminderMin); calendar.set(Calendar.MINUTE, habit.reminderMin);
calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.SECOND, 0);

@ -21,6 +21,8 @@ package org.isoron.uhabits.models;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.activeandroid.ActiveAndroid; import com.activeandroid.ActiveAndroid;
import com.activeandroid.Model; import com.activeandroid.Model;
@ -39,50 +41,113 @@ import java.util.List;
@Table(name = "Habits") @Table(name = "Habits")
public class Habit extends Model public class Habit extends Model
{ {
/**
* Name of the habit
*/
@Column(name = "name") @Column(name = "name")
public String name; public String name;
/**
* Description of the habit
*/
@Column(name = "description") @Column(name = "description")
public String description; public String description;
/**
* Frequency numerator. If a habit is performed 3 times in 7 days, this field equals 3.
*/
@Column(name = "freq_num") @Column(name = "freq_num")
public Integer freqNum; public Integer freqNum;
/**
* Frequency denominator. If a habit is performed 3 times in 7 days, this field equals 7.
*/
@Column(name = "freq_den") @Column(name = "freq_den")
public Integer freqDen; public Integer freqDen;
/**
* Color of the habit. The format is the same as android.graphics.Color.
*/
@Column(name = "color") @Column(name = "color")
public Integer color; public Integer color;
/**
* Position of the habit. Habits are usually sorted by this field.
*/
@Column(name = "position") @Column(name = "position")
public Integer position; public Integer position;
/**
* Hour of the day the reminder should be shown. If there is no reminder, this equals to null.
*/
@Nullable
@Column(name = "reminder_hour") @Column(name = "reminder_hour")
public Integer reminderHour; public Integer reminderHour;
/**
* Minute the reminder should be shown. If there is no reminder, this equals to null.
*/
@Nullable
@Column(name = "reminder_min") @Column(name = "reminder_min")
public Integer reminderMin; public Integer reminderMin;
/**
* Days of the week the reminder should be shown. This field can be converted to a list of
* booleans using the method DateHelper.unpackWeekdayList and converted back to an integer by
* using the method DateHelper.packWeekdayList. If there is no reminder, it equals null.
*/
@Nullable
@Column(name = "reminder_days") @Column(name = "reminder_days")
public Integer reminderDays; public Integer reminderDays;
/**
* Not currently used.
*/
@Column(name = "highlight") @Column(name = "highlight")
public Integer highlight; public Integer highlight;
/**
* Flag that indicates whether the habit is archived. Archived habits are usually omitted from
* listings, unless explicitly included.
*/
@Column(name = "archived") @Column(name = "archived")
public Integer archived; public Integer archived;
/**
* List of streaks belonging to this habit.
*/
public StreakList streaks; public StreakList streaks;
/**
* List of scores belonging to this habit.
*/
public ScoreList scores; public ScoreList scores;
/**
* List of repetitions belonging to this habit.
*/
public RepetitionList repetitions; public RepetitionList repetitions;
/**
* List of checkmarks belonging to this habit.
*/
public CheckmarkList checkmarks; public CheckmarkList checkmarks;
/**
* Constructs a habit with the same attributes as the specified habit.
*
* @param model the model whose attributes should be copied from
*/
public Habit(Habit model) public Habit(Habit model)
{ {
copyAttributes(model); copyAttributes(model);
initializeLists(); initializeLists();
} }
/**
* Constructs a habit with default attributes. The habit is not archived, not highlighted, has
* no reminders and is placed in the last position of the list of habits.
*/
public Habit() public Habit()
{ {
this.color = ColorHelper.palette[5]; this.color = ColorHelper.palette[5];
@ -91,7 +156,6 @@ public class Habit extends Model
this.archived = 0; this.archived = 0;
this.freqDen = 7; this.freqDen = 7;
this.freqNum = 3; this.freqNum = 3;
this.reminderDays = 127;
initializeLists(); initializeLists();
} }
@ -103,17 +167,36 @@ public class Habit extends Model
checkmarks = new CheckmarkList(this); checkmarks = new CheckmarkList(this);
} }
public static Habit get(Long id) /**
* Returns the habit with specified id.
*
* @param id the id of the habit
* @return the habit, or null if none exist
*/
@Nullable
public static Habit get(@NonNull Long id)
{ {
return Habit.load(Habit.class, id); return Habit.load(Habit.class, id);
} }
/**
* Returns a list of all habits, optionally including archived habits.
*
* @param includeArchive whether archived habits should be included the list
* @return list of all habits
*/
public static List<Habit> getAll(boolean includeArchive) public static List<Habit> getAll(boolean includeArchive)
{ {
if(includeArchive) return selectWithArchived().execute(); if(includeArchive) return selectWithArchived().execute();
else return select().execute(); else return select().execute();
} }
/**
* Changes the id of a habit on the database.
*
* @param oldId the original id
* @param newId the new id
*/
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
public static void updateId(long oldId, long newId) public static void updateId(long oldId, long newId)
{ {
@ -125,21 +208,32 @@ public class Habit extends Model
return new Select().from(Habit.class).where("archived = 0").orderBy("position"); return new Select().from(Habit.class).where("archived = 0").orderBy("position");
} }
public static From selectWithArchived() protected static From selectWithArchived()
{ {
return new Select().from(Habit.class).orderBy("position"); return new Select().from(Habit.class).orderBy("position");
} }
/**
* Returns the total number of unarchived habits.
*
* @return number of unarchived habits
*/
public static int count() public static int count()
{ {
return select().count(); return select().count();
} }
/**
* Returns the total number of habits, including archived habits.
*
* @return number of habits, including archived
*/
public static int countWithArchived() public static int countWithArchived()
{ {
return selectWithArchived().count(); return selectWithArchived().count();
} }
public static java.util.List<Habit> getHighlightedHabits() public static java.util.List<Habit> getHighlightedHabits()
{ {
return select().where("highlight = 1") return select().where("highlight = 1")
@ -147,11 +241,22 @@ public class Habit extends Model
.execute(); .execute();
} }
public static java.util.List<Habit> getHabitsWithReminder() /**
* Returns a list the habits that have a reminder. Does not include archived habits.
*
* @return list of habits with reminder
*/
public static List<Habit> getHabitsWithReminder()
{ {
return select().where("reminder_hour is not null").execute(); return select().where("reminder_hour is not null").execute();
} }
/**
* Changes the position of a habit in the list.
*
* @param from the habit that should be moved
* @param to the habit that currently occupies the desired position
*/
public static void reorder(Habit from, Habit to) public static void reorder(Habit from, Habit to)
{ {
if(from == to) return; if(from == to) return;
@ -173,6 +278,10 @@ public class Habit extends Model
from.save(); from.save();
} }
/**
* Recompute the field position for every habit in the database. It should never be necessary
* to call this method.
*/
public static void rebuildOrder() public static void rebuildOrder()
{ {
List<Habit> habits = selectWithArchived().execute(); List<Habit> habits = selectWithArchived().execute();
@ -196,6 +305,11 @@ public class Habit extends Model
} }
/**
* Copies all the attributes of the specified habit into this habit
*
* @param model the model whose attributes should be copied from
*/
public void copyAttributes(Habit model) public void copyAttributes(Habit model)
{ {
this.name = model.name; this.name = model.name;
@ -211,12 +325,21 @@ public class Habit extends Model
this.archived = model.archived; this.archived = model.archived;
} }
/**
* Saves the habit on the database, and assigns the specified id to it.
*
* @param id the id that the habit should receive
*/
public void save(Long id) public void save(Long id)
{ {
save(); save();
Habit.updateId(getId(), id); Habit.updateId(getId(), id);
} }
/**
* Deletes the habit and all data associated to it, including checkmarks, repetitions and
* scores.
*/
public void cascadeDelete() public void cascadeDelete()
{ {
Long id = getId(); Long id = getId();
@ -238,25 +361,93 @@ public class Habit extends Model
} }
} }
/**
* Returns the public URI that identifies this habit
* @return the uri
*/
public Uri getUri() public Uri getUri()
{ {
return Uri.parse(String.format("content://org.isoron.uhabits/habit/%d", getId())); return Uri.parse(String.format("content://org.isoron.uhabits/habit/%d", getId()));
} }
public void archive() /**
* Returns whether the habit is archived or not.
* @return true if archived
*/
public boolean isArchived()
{ {
archived = 1; return archived != 0;
save();
} }
public void unarchive() private static void updateAttributes(List<Habit> habits, Integer color, Integer archived)
{ {
archived = 0; ActiveAndroid.beginTransaction();
save();
try
{
for (Habit h : habits)
{
if(color != null) h.color = color;
if(archived != null) h.archived = archived;
h.save();
}
ActiveAndroid.setTransactionSuccessful();
}
finally
{
ActiveAndroid.endTransaction();
}
} }
public boolean isArchived() /**
* Archives an entire list of habits
*
* @param habits the habits to be archived
*/
public static void archive(List<Habit> habits)
{ {
return archived != 0; updateAttributes(habits, null, 1);
}
/**
* Unarchives an entire list of habits
*
* @param habits the habits to be unarchived
*/
public static void unarchive(List<Habit> habits)
{
updateAttributes(habits, null, 0);
}
/**
* Sets the color for an entire list of habits.
*
* @param habits the habits to be modified
* @param color the new color to be set
*/
public static void setColor(List<Habit> habits, int color)
{
updateAttributes(habits, color, null);
}
/**
* Checks whether the habit has a reminder set.
*
* @return true if habit has reminder
*/
public boolean hasReminder()
{
return (reminderHour != null && reminderMin != null && reminderDays != null);
}
/**
* Clears the reminder for a habit. This sets all the related fields to null.
*/
public void clearReminder()
{
reminderHour = null;
reminderMin = null;
reminderDays = null;
} }
} }

Loading…
Cancel
Save