diff --git a/app/src/androidTest/java/org/isoron/uhabits/unit/models/HabitTest.java b/app/src/androidTest/java/org/isoron/uhabits/unit/models/HabitTest.java
index d46826974..f31db5f35 100644
--- a/app/src/androidTest/java/org/isoron/uhabits/unit/models/HabitTest.java
+++ b/app/src/androidTest/java/org/isoron/uhabits/unit/models/HabitTest.java
@@ -19,6 +19,7 @@
package org.isoron.uhabits.unit.models;
+import android.graphics.Color;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
@@ -31,6 +32,8 @@ import java.util.LinkedList;
import java.util.List;
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;
@RunWith(AndroidJUnit4.class)
@@ -43,6 +46,49 @@ public class HabitTest
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
public void reorderTest()
{
diff --git a/app/src/main/java/org/isoron/helpers/DateHelper.java b/app/src/main/java/org/isoron/helpers/DateHelper.java
index 361b18cac..f89a3ef7b 100644
--- a/app/src/main/java/org/isoron/helpers/DateHelper.java
+++ b/app/src/main/java/org/isoron/helpers/DateHelper.java
@@ -32,6 +32,8 @@ import java.util.TimeZone;
public class DateHelper
{
public static long millisecondsInOneDay = 24 * 60 * 60 * 1000;
+ public static int ALL_WEEK_DAYS = 127;
+
private static Long fixedLocalTime = null;
public static long getLocalTime()
diff --git a/app/src/main/java/org/isoron/helpers/DialogHelper.java b/app/src/main/java/org/isoron/helpers/DialogHelper.java
index ebaf6c9b5..c24083a7b 100644
--- a/app/src/main/java/org/isoron/helpers/DialogHelper.java
+++ b/app/src/main/java/org/isoron/helpers/DialogHelper.java
@@ -32,6 +32,7 @@ import android.view.View;
import android.view.inputmethod.InputMethodManager;
import org.isoron.uhabits.BuildConfig;
+import org.isoron.uhabits.commands.Command;
public abstract class DialogHelper
{
diff --git a/app/src/main/java/org/isoron/helpers/ReplayableActivity.java b/app/src/main/java/org/isoron/helpers/ReplayableActivity.java
index d2fcdc350..8f35b4bc7 100644
--- a/app/src/main/java/org/isoron/helpers/ReplayableActivity.java
+++ b/app/src/main/java/org/isoron/helpers/ReplayableActivity.java
@@ -26,6 +26,7 @@ import android.os.Bundle;
import android.widget.Toast;
import org.isoron.uhabits.R;
+import org.isoron.uhabits.commands.Command;
import java.util.LinkedList;
diff --git a/app/src/main/java/org/isoron/uhabits/commands/ArchiveHabitsCommand.java b/app/src/main/java/org/isoron/uhabits/commands/ArchiveHabitsCommand.java
index 3aee23dc1..5e77c87d1 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/ArchiveHabitsCommand.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/ArchiveHabitsCommand.java
@@ -19,7 +19,6 @@
package org.isoron.uhabits.commands;
-import org.isoron.helpers.Command;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
@@ -45,15 +44,13 @@ public class ArchiveHabitsCommand extends Command
@Override
public void execute()
{
- for(Habit h : habits)
- h.archive();
+ Habit.archive(habits);
}
@Override
public void undo()
{
- for(Habit h : habits)
- h.unarchive();
+ Habit.unarchive(habits);
}
public Integer getExecuteStringId()
diff --git a/app/src/main/java/org/isoron/uhabits/commands/ChangeHabitColorCommand.java b/app/src/main/java/org/isoron/uhabits/commands/ChangeHabitColorCommand.java
index f9b00ba89..9abf7d5a7 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/ChangeHabitColorCommand.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/ChangeHabitColorCommand.java
@@ -21,7 +21,6 @@ package org.isoron.uhabits.commands;
import com.activeandroid.ActiveAndroid;
-import org.isoron.helpers.Command;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
@@ -47,22 +46,7 @@ public class ChangeHabitColorCommand extends Command
@Override
public void execute()
{
- ActiveAndroid.beginTransaction();
-
- try
- {
- for(Habit h : habits)
- {
- h.color = newColor;
- h.save();
- }
-
- ActiveAndroid.setTransactionSuccessful();
- }
- finally
- {
- ActiveAndroid.endTransaction();
- }
+ Habit.setColor(habits, newColor);
}
@Override
diff --git a/app/src/main/java/org/isoron/helpers/Command.java b/app/src/main/java/org/isoron/uhabits/commands/Command.java
similarity index 96%
rename from app/src/main/java/org/isoron/helpers/Command.java
rename to app/src/main/java/org/isoron/uhabits/commands/Command.java
index 7472b096f..b9427e38a 100644
--- a/app/src/main/java/org/isoron/helpers/Command.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/Command.java
@@ -17,7 +17,7 @@
* with this program. If not, see .
*/
-package org.isoron.helpers;
+package org.isoron.uhabits.commands;
public abstract class Command
{
diff --git a/app/src/main/java/org/isoron/uhabits/commands/CommandFailedException.java b/app/src/main/java/org/isoron/uhabits/commands/CommandFailedException.java
new file mode 100644
index 000000000..b64722a88
--- /dev/null
+++ b/app/src/main/java/org/isoron/uhabits/commands/CommandFailedException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 Á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.commands;
+
+public class CommandFailedException extends RuntimeException
+{
+ public CommandFailedException()
+ {
+ super();
+ }
+
+ public CommandFailedException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/app/src/main/java/org/isoron/uhabits/commands/CreateHabitCommand.java b/app/src/main/java/org/isoron/uhabits/commands/CreateHabitCommand.java
index e3fba3e35..b3fe9499f 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/CreateHabitCommand.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/CreateHabitCommand.java
@@ -19,7 +19,6 @@
package org.isoron.uhabits.commands;
-import org.isoron.helpers.Command;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
@@ -51,7 +50,10 @@ public class CreateHabitCommand extends Command
@Override
public void undo()
{
- Habit.get(savedId).delete();
+ Habit habit = Habit.get(savedId);
+ if(habit == null) throw new CommandFailedException("Habit not found");
+
+ habit.delete();
}
@Override
diff --git a/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java b/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java
index b1c2ee217..34e26c50c 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java
@@ -19,7 +19,6 @@
package org.isoron.uhabits.commands;
-import org.isoron.helpers.Command;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
diff --git a/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java b/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java
index ccd641c8b..aaca085d6 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java
@@ -19,7 +19,6 @@
package org.isoron.uhabits.commands;
-import org.isoron.helpers.Command;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
@@ -43,6 +42,8 @@ public class EditHabitCommand extends Command
public void execute()
{
Habit habit = Habit.get(savedId);
+ if(habit == null) throw new CommandFailedException("Habit not found");
+
habit.copyAttributes(modified);
habit.save();
if (hasIntervalChanged)
@@ -56,6 +57,8 @@ public class EditHabitCommand extends Command
public void undo()
{
Habit habit = Habit.get(savedId);
+ if(habit == null) throw new CommandFailedException("Habit not found");
+
habit.copyAttributes(original);
habit.save();
if (hasIntervalChanged)
diff --git a/app/src/main/java/org/isoron/uhabits/commands/ToggleRepetitionCommand.java b/app/src/main/java/org/isoron/uhabits/commands/ToggleRepetitionCommand.java
index fe573ddaf..451908433 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/ToggleRepetitionCommand.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/ToggleRepetitionCommand.java
@@ -19,7 +19,6 @@
package org.isoron.uhabits.commands;
-import org.isoron.helpers.Command;
import org.isoron.uhabits.models.Habit;
public class ToggleRepetitionCommand extends Command
diff --git a/app/src/main/java/org/isoron/uhabits/commands/UnarchiveHabitsCommand.java b/app/src/main/java/org/isoron/uhabits/commands/UnarchiveHabitsCommand.java
index 08d34af69..79bd01d6e 100644
--- a/app/src/main/java/org/isoron/uhabits/commands/UnarchiveHabitsCommand.java
+++ b/app/src/main/java/org/isoron/uhabits/commands/UnarchiveHabitsCommand.java
@@ -19,7 +19,6 @@
package org.isoron.uhabits.commands;
-import org.isoron.helpers.Command;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
@@ -45,15 +44,13 @@ public class UnarchiveHabitsCommand extends Command
@Override
public void execute()
{
- for(Habit h : habits)
- h.unarchive();
+ Habit.unarchive(habits);
}
@Override
public void undo()
{
- for(Habit h : habits)
- h.archive();
+ Habit.archive(habits);
}
public Integer getExecuteStringId()
diff --git a/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java
index a48087023..eddf1068e 100644
--- a/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java
+++ b/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java
@@ -39,16 +39,17 @@ import com.android.datetimepicker.time.RadialPickerLayout;
import com.android.datetimepicker.time.TimePickerDialog;
import org.isoron.helpers.ColorHelper;
-import org.isoron.helpers.Command;
import org.isoron.helpers.DateHelper;
import org.isoron.helpers.DialogHelper.OnSavedListener;
import org.isoron.uhabits.R;
+import org.isoron.uhabits.commands.Command;
import org.isoron.uhabits.commands.CreateHabitCommand;
import org.isoron.uhabits.commands.EditHabitCommand;
import org.isoron.uhabits.dialogs.WeekdayPickerDialog;
import org.isoron.uhabits.models.Habit;
import java.util.Arrays;
+import java.util.Date;
public class EditHabitFragment extends DialogFragment
implements OnClickListener, WeekdayPickerDialog.OnWeekdaysPickedListener,
@@ -136,7 +137,10 @@ public class EditHabitFragment extends DialogFragment
}
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);
getDialog().setTitle(R.string.edit_habit);
@@ -178,14 +182,18 @@ public class EditHabitFragment extends DialogFragment
editor.apply();
}
+ @SuppressWarnings("ConstantConditions")
private void updateReminder()
{
- if (modifiedHabit.reminderHour != null)
+ if (modifiedHabit.hasReminder())
{
tvReminderTime.setTextColor(Color.BLACK);
tvReminderTime.setText(DateHelper.formatTime(getActivity(), modifiedHabit.reminderHour,
modifiedHabit.reminderMin));
tvReminderDays.setVisibility(View.VISIBLE);
+
+ boolean weekdays[] = DateHelper.unpackWeekdayList(modifiedHabit.reminderDays);
+ tvReminderDays.setText(DateHelper.formatWeekdayList(getActivity(), weekdays));
}
else
{
@@ -193,9 +201,6 @@ public class EditHabitFragment extends DialogFragment
tvReminderTime.setText(R.string.reminder_off);
tvReminderDays.setVisibility(View.GONE);
}
-
- boolean weekdays[] = DateHelper.unpackWeekdayList(modifiedHabit.reminderDays);
- tvReminderDays.setText(DateHelper.formatWeekdayList(getActivity(), weekdays));
}
public void setOnSavedListener(OnSavedListener onSavedListener)
@@ -303,12 +308,13 @@ public class EditHabitFragment extends DialogFragment
return valid;
}
+ @SuppressWarnings("ConstantConditions")
private void onDateSpinnerClick()
{
int defaultHour = 8;
int defaultMin = 0;
- if (modifiedHabit.reminderHour != null)
+ if (modifiedHabit.hasReminder())
{
defaultHour = modifiedHabit.reminderHour;
defaultMin = modifiedHabit.reminderMin;
@@ -319,8 +325,11 @@ public class EditHabitFragment extends DialogFragment
timePicker.show(getFragmentManager(), "timePicker");
}
+ @SuppressWarnings("ConstantConditions")
private void onWeekdayClick()
{
+ if(!modifiedHabit.hasReminder()) return;
+
WeekdayPickerDialog dialog = new WeekdayPickerDialog();
dialog.setListener(this);
dialog.setSelectedDays(DateHelper.unpackWeekdayList(modifiedHabit.reminderDays));
@@ -332,14 +341,14 @@ public class EditHabitFragment extends DialogFragment
{
modifiedHabit.reminderHour = hour;
modifiedHabit.reminderMin = minute;
+ modifiedHabit.reminderDays = DateHelper.ALL_WEEK_DAYS;
updateReminder();
}
@Override
public void onTimeCleared(RadialPickerLayout view)
{
- modifiedHabit.reminderHour = null;
- modifiedHabit.reminderMin = null;
+ modifiedHabit.clearReminder();
updateReminder();
}
@@ -357,12 +366,14 @@ public class EditHabitFragment extends DialogFragment
}
@Override
+ @SuppressWarnings("ConstantConditions")
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt("color", modifiedHabit.color);
- if(modifiedHabit.reminderHour != null)
+
+ if(modifiedHabit.hasReminder())
{
outState.putInt("reminderMin", modifiedHabit.reminderMin);
outState.putInt("reminderHour", modifiedHabit.reminderHour);
diff --git a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java
index ef11a2301..51b24d696 100644
--- a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java
+++ b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java
@@ -46,7 +46,7 @@ import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
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.DialogHelper;
import org.isoron.helpers.DialogHelper.OnSavedListener;
diff --git a/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java
index 1b7817afb..ba6c82d41 100644
--- a/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java
+++ b/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java
@@ -33,7 +33,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import org.isoron.helpers.ColorHelper;
-import org.isoron.helpers.Command;
+import org.isoron.uhabits.commands.Command;
import org.isoron.helpers.DialogHelper;
import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R;
diff --git a/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java b/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java
index 9a0e691d0..3f515396b 100644
--- a/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java
+++ b/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
+import android.support.annotation.Nullable;
import android.util.Log;
import org.isoron.helpers.DateHelper;
@@ -43,13 +44,17 @@ public class ReminderHelper
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)
{
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
+ //noinspection ConstantConditions
calendar.set(Calendar.HOUR_OF_DAY, habit.reminderHour);
+ //noinspection ConstantConditions
calendar.set(Calendar.MINUTE, habit.reminderMin);
calendar.set(Calendar.SECOND, 0);
diff --git a/app/src/main/java/org/isoron/uhabits/models/Habit.java b/app/src/main/java/org/isoron/uhabits/models/Habit.java
index 02e3e67b6..851077189 100644
--- a/app/src/main/java/org/isoron/uhabits/models/Habit.java
+++ b/app/src/main/java/org/isoron/uhabits/models/Habit.java
@@ -21,6 +21,8 @@ package org.isoron.uhabits.models;
import android.annotation.SuppressLint;
import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import com.activeandroid.ActiveAndroid;
import com.activeandroid.Model;
@@ -39,50 +41,113 @@ import java.util.List;
@Table(name = "Habits")
public class Habit extends Model
{
+ /**
+ * Name of the habit
+ */
@Column(name = "name")
public String name;
+ /**
+ * Description of the habit
+ */
@Column(name = "description")
public String description;
+ /**
+ * Frequency numerator. If a habit is performed 3 times in 7 days, this field equals 3.
+ */
@Column(name = "freq_num")
public Integer freqNum;
+ /**
+ * Frequency denominator. If a habit is performed 3 times in 7 days, this field equals 7.
+ */
@Column(name = "freq_den")
public Integer freqDen;
+ /**
+ * Color of the habit. The format is the same as android.graphics.Color.
+ */
@Column(name = "color")
public Integer color;
+ /**
+ * Position of the habit. Habits are usually sorted by this field.
+ */
@Column(name = "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")
public Integer reminderHour;
+ /**
+ * Minute the reminder should be shown. If there is no reminder, this equals to null.
+ */
+ @Nullable
@Column(name = "reminder_min")
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")
public Integer reminderDays;
+ /**
+ * Not currently used.
+ */
@Column(name = "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")
public Integer archived;
+ /**
+ * List of streaks belonging to this habit.
+ */
public StreakList streaks;
+
+ /**
+ * List of scores belonging to this habit.
+ */
public ScoreList scores;
+
+ /**
+ * List of repetitions belonging to this habit.
+ */
public RepetitionList repetitions;
+
+ /**
+ * List of checkmarks belonging to this habit.
+ */
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)
{
copyAttributes(model);
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()
{
this.color = ColorHelper.palette[5];
@@ -91,7 +156,6 @@ public class Habit extends Model
this.archived = 0;
this.freqDen = 7;
this.freqNum = 3;
- this.reminderDays = 127;
initializeLists();
}
@@ -103,17 +167,36 @@ public class Habit extends Model
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);
}
+ /**
+ * 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 getAll(boolean includeArchive)
{
if(includeArchive) return selectWithArchived().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")
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");
}
- public static From selectWithArchived()
+ protected static From selectWithArchived()
{
return new Select().from(Habit.class).orderBy("position");
}
+ /**
+ * Returns the total number of unarchived habits.
+ *
+ * @return number of unarchived habits
+ */
public static int count()
{
return select().count();
}
+ /**
+ * Returns the total number of habits, including archived habits.
+ *
+ * @return number of habits, including archived
+ */
public static int countWithArchived()
{
return selectWithArchived().count();
}
+
public static java.util.List getHighlightedHabits()
{
return select().where("highlight = 1")
@@ -147,11 +241,22 @@ public class Habit extends Model
.execute();
}
- public static java.util.List getHabitsWithReminder()
+ /**
+ * Returns a list the habits that have a reminder. Does not include archived habits.
+ *
+ * @return list of habits with reminder
+ */
+ public static List getHabitsWithReminder()
{
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)
{
if(from == to) return;
@@ -173,6 +278,10 @@ public class Habit extends Model
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()
{
List 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)
{
this.name = model.name;
@@ -211,12 +325,21 @@ public class Habit extends Model
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)
{
save();
Habit.updateId(getId(), id);
}
+ /**
+ * Deletes the habit and all data associated to it, including checkmarks, repetitions and
+ * scores.
+ */
public void cascadeDelete()
{
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()
{
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;
- save();
+ return archived != 0;
}
- public void unarchive()
+ private static void updateAttributes(List habits, Integer color, Integer archived)
{
- archived = 0;
- save();
+ ActiveAndroid.beginTransaction();
+
+ 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 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 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 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;
}
}