Loading src/org/dmfs/tasks/model/CheckListItem.java 0 → 100644 +14 −0 Original line number Diff line number Diff line package org.dmfs.tasks.model; public final class CheckListItem { public boolean checked; public String text; public CheckListItem(boolean checked, String text) { this.checked = checked; this.text = text; } } src/org/dmfs/tasks/model/DefaultModel.java +2 −2 Original line number Diff line number Diff line Loading @@ -96,8 +96,8 @@ public class DefaultModel extends Model mFields.add(new FieldDescriptor(mContext, R.string.task_location, TaskFieldAdapters.LOCATION).setViewLayout(TEXT_VIEW).setEditorLayout(TEXT_EDIT)); // description mFields.add(new FieldDescriptor(mContext, R.string.task_description, TaskFieldAdapters.DESCRIPTION).setViewLayout(CHECKLIST_VIEW).setEditorLayout( CHECKLIST_EDIT)); mFields.add(new FieldDescriptor(mContext, R.string.task_description, TaskFieldAdapters.DESCRIPTION).setViewLayout(TEXT_VIEW).setEditorLayout( TEXT_EDIT)); // start mFields.add(new FieldDescriptor(mContext, R.string.task_start, TaskFieldAdapters.DTSTART).setViewLayout(TIME_VIEW).setEditorLayout(TIME_EDIT)); Loading src/org/dmfs/tasks/model/TaskFieldAdapters.java +2 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ package org.dmfs.tasks.model; import org.dmfs.provider.tasks.TaskContract; import org.dmfs.provider.tasks.TaskContract.Tasks; import org.dmfs.tasks.model.adapters.BooleanFieldAdapter; import org.dmfs.tasks.model.adapters.DescriptionStringFieldAdapter; import org.dmfs.tasks.model.adapters.FloatFieldAdapter; import org.dmfs.tasks.model.adapters.IntegerFieldAdapter; import org.dmfs.tasks.model.adapters.StringFieldAdapter; Loading @@ -27,7 +28,6 @@ import org.dmfs.tasks.model.adapters.TimeFieldAdapter; import org.dmfs.tasks.model.adapters.TimezoneFieldAdapter; import org.dmfs.tasks.model.adapters.UrlFieldAdapter; import org.dmfs.tasks.model.contraints.AdjustPercentComplete; import org.dmfs.tasks.model.contraints.ChecklistConstraint; import org.dmfs.tasks.model.contraints.NotAfter; import org.dmfs.tasks.model.contraints.NotBefore; Loading Loading @@ -88,8 +88,7 @@ public final class TaskFieldAdapters /** * Adapter for the description of a task. */ public final static StringFieldAdapter DESCRIPTION = (StringFieldAdapter) new StringFieldAdapter(Tasks.DESCRIPTION).addContraint(new ChecklistConstraint( STATUS, PERCENT_COMPLETE)); public final static DescriptionStringFieldAdapter DESCRIPTION = new DescriptionStringFieldAdapter(Tasks.DESCRIPTION); /** * Private adapter for the start date of a task. We need this to reference DTSTART from DUE. Loading src/org/dmfs/tasks/model/XmlModel.java +2 −2 Original line number Diff line number Diff line Loading @@ -384,8 +384,8 @@ public class XmlModel extends Model FIELD_INFLATER_MAP.put("title", new FieldInflater(TaskFieldAdapters.TITLE, R.string.task_title, R.layout.text_field_view, R.layout.text_field_editor)); FIELD_INFLATER_MAP.put("location", new FieldInflater(TaskFieldAdapters.LOCATION, R.string.task_location, R.layout.text_field_view, R.layout.text_field_editor)); FIELD_INFLATER_MAP.put("description", new FieldInflater(TaskFieldAdapters.DESCRIPTION, R.string.task_description, R.layout.checklist_field_view, R.layout.checklist_field_editor)); FIELD_INFLATER_MAP.put("description", new FieldInflater(TaskFieldAdapters.DESCRIPTION, R.string.task_description, R.layout.text_field_view, R.layout.text_field_editor)); FIELD_INFLATER_MAP.put("dtstart", new FieldInflater(TaskFieldAdapters.DTSTART, R.string.task_start, R.layout.time_field_view, R.layout.time_field_editor)); Loading src/org/dmfs/tasks/model/adapters/ChecklistFieldAdapter.java 0 → 100644 +221 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 Marten Gajda <marten@dmfs.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.dmfs.tasks.model.adapters; import java.util.ArrayList; import java.util.List; import org.dmfs.tasks.model.CheckListItem; import org.dmfs.tasks.model.ContentSet; import org.dmfs.tasks.model.OnContentChangeListener; import android.database.Cursor; /** * Knows how to load and store check list from/to a combined description/check list field. * * @author Marten Gajda <marten@dmfs.org> */ public final class ChecklistFieldAdapter extends FieldAdapter<List<CheckListItem>> { /** * The field name this adapter uses to store the values. */ private final String mFieldName; /** * The default value, if any. */ private final List<CheckListItem> mDefaultValue; /** * Constructor for a new StringFieldAdapter without default value. * * @param fieldName * The name of the field to use when loading or storing the value. */ public ChecklistFieldAdapter(String fieldName) { this(fieldName, null); } /** * Constructor for a new StringFieldAdapter without default value. * * @param fieldName * The name of the field to use when loading or storing the value. * @param defaultValue * The default check list */ public ChecklistFieldAdapter(String fieldName, List<CheckListItem> defaultValue) { if (fieldName == null) { throw new IllegalArgumentException("fieldName must not be null"); } mFieldName = fieldName; mDefaultValue = defaultValue; } @Override public List<CheckListItem> get(ContentSet values) { // return the check list return extractCheckList(values.getAsString(mFieldName)); } @Override public List<CheckListItem> get(Cursor cursor) { int columnIdx = cursor.getColumnIndex(mFieldName); if (columnIdx < 0) { throw new IllegalArgumentException("The fieldName column missing in cursor."); } return extractCheckList(cursor.getString(columnIdx)); } @Override public List<CheckListItem> getDefault(ContentSet values) { return mDefaultValue; } @Override public void set(ContentSet values, List<CheckListItem> value) { String oldDescription = DescriptionStringFieldAdapter.extractDescription(values.getAsString(mFieldName)); if (value != null && value.size() > 0) { StringBuilder sb = new StringBuilder(1024); if (oldDescription != null) { sb.append(oldDescription); sb.append("\n"); } serializeCheckList(sb, value); values.put(mFieldName, sb.toString()); } else { // store the current value just without check list values.put(mFieldName, oldDescription); } } @Override public void registerListener(ContentSet values, OnContentChangeListener listener, boolean initalNotification) { values.addOnChangeListener(listener, mFieldName, initalNotification); } @Override public void unregisterListener(ContentSet values, OnContentChangeListener listener) { values.removeOnChangeListener(listener, mFieldName); } private static List<CheckListItem> extractCheckList(String value) { if (value != null && value.length() >= 3) { int checklistpos = -1; while ((checklistpos = value.indexOf("[", checklistpos + 1)) >= 0) { if (value.length() > checklistpos + 2 && value.charAt(checklistpos + 2) == ']' && (checklistpos == 0 || value.charAt(checklistpos - 1) == '\n')) { char checkmark = value.charAt(checklistpos + 1); if (checkmark == ' ' || checkmark == 'x' || checkmark == 'X') { return parseCheckList(value.substring(checklistpos)); } } } } return new ArrayList<CheckListItem>(4); } private static List<CheckListItem> parseCheckList(String checklist) { List<CheckListItem> result = new ArrayList<CheckListItem>(16); String[] lines = checklist.split("\n"); for (String line : lines) { line = line.trim(); if (line.length() == 0) { // skip empty lines continue; } if (line.startsWith("[x]") || line.startsWith("[X]")) { result.add(new CheckListItem(true, line.substring(3).trim())); } else if (line.startsWith("[ ]")) { result.add(new CheckListItem(false, line.substring(3).trim())); } else { result.add(new CheckListItem(false, line)); } } return result; } private static void serializeCheckList(StringBuilder sb, List<CheckListItem> checklist) { if (checklist == null || checklist.size() == 0) { return; } boolean first = true; for (CheckListItem item : checklist) { if (first) { first = false; } else { sb.append('\n'); } sb.append(item.checked ? "[x] " : "[ ] "); sb.append(item.text); } } } Loading
src/org/dmfs/tasks/model/CheckListItem.java 0 → 100644 +14 −0 Original line number Diff line number Diff line package org.dmfs.tasks.model; public final class CheckListItem { public boolean checked; public String text; public CheckListItem(boolean checked, String text) { this.checked = checked; this.text = text; } }
src/org/dmfs/tasks/model/DefaultModel.java +2 −2 Original line number Diff line number Diff line Loading @@ -96,8 +96,8 @@ public class DefaultModel extends Model mFields.add(new FieldDescriptor(mContext, R.string.task_location, TaskFieldAdapters.LOCATION).setViewLayout(TEXT_VIEW).setEditorLayout(TEXT_EDIT)); // description mFields.add(new FieldDescriptor(mContext, R.string.task_description, TaskFieldAdapters.DESCRIPTION).setViewLayout(CHECKLIST_VIEW).setEditorLayout( CHECKLIST_EDIT)); mFields.add(new FieldDescriptor(mContext, R.string.task_description, TaskFieldAdapters.DESCRIPTION).setViewLayout(TEXT_VIEW).setEditorLayout( TEXT_EDIT)); // start mFields.add(new FieldDescriptor(mContext, R.string.task_start, TaskFieldAdapters.DTSTART).setViewLayout(TIME_VIEW).setEditorLayout(TIME_EDIT)); Loading
src/org/dmfs/tasks/model/TaskFieldAdapters.java +2 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ package org.dmfs.tasks.model; import org.dmfs.provider.tasks.TaskContract; import org.dmfs.provider.tasks.TaskContract.Tasks; import org.dmfs.tasks.model.adapters.BooleanFieldAdapter; import org.dmfs.tasks.model.adapters.DescriptionStringFieldAdapter; import org.dmfs.tasks.model.adapters.FloatFieldAdapter; import org.dmfs.tasks.model.adapters.IntegerFieldAdapter; import org.dmfs.tasks.model.adapters.StringFieldAdapter; Loading @@ -27,7 +28,6 @@ import org.dmfs.tasks.model.adapters.TimeFieldAdapter; import org.dmfs.tasks.model.adapters.TimezoneFieldAdapter; import org.dmfs.tasks.model.adapters.UrlFieldAdapter; import org.dmfs.tasks.model.contraints.AdjustPercentComplete; import org.dmfs.tasks.model.contraints.ChecklistConstraint; import org.dmfs.tasks.model.contraints.NotAfter; import org.dmfs.tasks.model.contraints.NotBefore; Loading Loading @@ -88,8 +88,7 @@ public final class TaskFieldAdapters /** * Adapter for the description of a task. */ public final static StringFieldAdapter DESCRIPTION = (StringFieldAdapter) new StringFieldAdapter(Tasks.DESCRIPTION).addContraint(new ChecklistConstraint( STATUS, PERCENT_COMPLETE)); public final static DescriptionStringFieldAdapter DESCRIPTION = new DescriptionStringFieldAdapter(Tasks.DESCRIPTION); /** * Private adapter for the start date of a task. We need this to reference DTSTART from DUE. Loading
src/org/dmfs/tasks/model/XmlModel.java +2 −2 Original line number Diff line number Diff line Loading @@ -384,8 +384,8 @@ public class XmlModel extends Model FIELD_INFLATER_MAP.put("title", new FieldInflater(TaskFieldAdapters.TITLE, R.string.task_title, R.layout.text_field_view, R.layout.text_field_editor)); FIELD_INFLATER_MAP.put("location", new FieldInflater(TaskFieldAdapters.LOCATION, R.string.task_location, R.layout.text_field_view, R.layout.text_field_editor)); FIELD_INFLATER_MAP.put("description", new FieldInflater(TaskFieldAdapters.DESCRIPTION, R.string.task_description, R.layout.checklist_field_view, R.layout.checklist_field_editor)); FIELD_INFLATER_MAP.put("description", new FieldInflater(TaskFieldAdapters.DESCRIPTION, R.string.task_description, R.layout.text_field_view, R.layout.text_field_editor)); FIELD_INFLATER_MAP.put("dtstart", new FieldInflater(TaskFieldAdapters.DTSTART, R.string.task_start, R.layout.time_field_view, R.layout.time_field_editor)); Loading
src/org/dmfs/tasks/model/adapters/ChecklistFieldAdapter.java 0 → 100644 +221 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 Marten Gajda <marten@dmfs.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.dmfs.tasks.model.adapters; import java.util.ArrayList; import java.util.List; import org.dmfs.tasks.model.CheckListItem; import org.dmfs.tasks.model.ContentSet; import org.dmfs.tasks.model.OnContentChangeListener; import android.database.Cursor; /** * Knows how to load and store check list from/to a combined description/check list field. * * @author Marten Gajda <marten@dmfs.org> */ public final class ChecklistFieldAdapter extends FieldAdapter<List<CheckListItem>> { /** * The field name this adapter uses to store the values. */ private final String mFieldName; /** * The default value, if any. */ private final List<CheckListItem> mDefaultValue; /** * Constructor for a new StringFieldAdapter without default value. * * @param fieldName * The name of the field to use when loading or storing the value. */ public ChecklistFieldAdapter(String fieldName) { this(fieldName, null); } /** * Constructor for a new StringFieldAdapter without default value. * * @param fieldName * The name of the field to use when loading or storing the value. * @param defaultValue * The default check list */ public ChecklistFieldAdapter(String fieldName, List<CheckListItem> defaultValue) { if (fieldName == null) { throw new IllegalArgumentException("fieldName must not be null"); } mFieldName = fieldName; mDefaultValue = defaultValue; } @Override public List<CheckListItem> get(ContentSet values) { // return the check list return extractCheckList(values.getAsString(mFieldName)); } @Override public List<CheckListItem> get(Cursor cursor) { int columnIdx = cursor.getColumnIndex(mFieldName); if (columnIdx < 0) { throw new IllegalArgumentException("The fieldName column missing in cursor."); } return extractCheckList(cursor.getString(columnIdx)); } @Override public List<CheckListItem> getDefault(ContentSet values) { return mDefaultValue; } @Override public void set(ContentSet values, List<CheckListItem> value) { String oldDescription = DescriptionStringFieldAdapter.extractDescription(values.getAsString(mFieldName)); if (value != null && value.size() > 0) { StringBuilder sb = new StringBuilder(1024); if (oldDescription != null) { sb.append(oldDescription); sb.append("\n"); } serializeCheckList(sb, value); values.put(mFieldName, sb.toString()); } else { // store the current value just without check list values.put(mFieldName, oldDescription); } } @Override public void registerListener(ContentSet values, OnContentChangeListener listener, boolean initalNotification) { values.addOnChangeListener(listener, mFieldName, initalNotification); } @Override public void unregisterListener(ContentSet values, OnContentChangeListener listener) { values.removeOnChangeListener(listener, mFieldName); } private static List<CheckListItem> extractCheckList(String value) { if (value != null && value.length() >= 3) { int checklistpos = -1; while ((checklistpos = value.indexOf("[", checklistpos + 1)) >= 0) { if (value.length() > checklistpos + 2 && value.charAt(checklistpos + 2) == ']' && (checklistpos == 0 || value.charAt(checklistpos - 1) == '\n')) { char checkmark = value.charAt(checklistpos + 1); if (checkmark == ' ' || checkmark == 'x' || checkmark == 'X') { return parseCheckList(value.substring(checklistpos)); } } } } return new ArrayList<CheckListItem>(4); } private static List<CheckListItem> parseCheckList(String checklist) { List<CheckListItem> result = new ArrayList<CheckListItem>(16); String[] lines = checklist.split("\n"); for (String line : lines) { line = line.trim(); if (line.length() == 0) { // skip empty lines continue; } if (line.startsWith("[x]") || line.startsWith("[X]")) { result.add(new CheckListItem(true, line.substring(3).trim())); } else if (line.startsWith("[ ]")) { result.add(new CheckListItem(false, line.substring(3).trim())); } else { result.add(new CheckListItem(false, line)); } } return result; } private static void serializeCheckList(StringBuilder sb, List<CheckListItem> checklist) { if (checklist == null || checklist.size() == 0) { return; } boolean first = true; for (CheckListItem item : checklist) { if (first) { first = false; } else { sb.append('\n'); } sb.append(item.checked ? "[x] " : "[ ] "); sb.append(item.text); } } }