You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Notes-master/TaskList.java

483 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* 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 net.micode.notes.gtask.data;
// 导入Android SDK中用于数据库操作、日志记录的类
import android.database.Cursor;
import android.util.Log;
// 导入项目中用于笔记数据操作的类
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
// 导入项目中定义的异常类
import net.micode.notes.gtask.exception.ActionFailureException;
// 导入项目中的工具类用于处理GTask相关的字符串常量
import net.micode.notes.tool.GTaskStringUtils;
// 导入JSON处理相关的类
import org.json.JSONException;
import org.json.JSONObject;
// 导入Java的ArrayList用于存储任务列表
import java.util.ArrayList;
/**
* TaskList类继承自Node类表示一个任务列表
*/
public class TaskList extends Node {
// 类的标签,用于日志记录
private static final String TAG = TaskList.class.getSimpleName();
// 任务列表的索引
private int mIndex;
// 任务列表中的子任务集合
private ArrayList<Task> mChildren;
/**
* 构造函数,初始化任务列表的属性
*/
public TaskList() {
super();
mChildren = new ArrayList<Task>();
mIndex = 1;
}
/**
* 生成创建任务列表的JSON对象
* @param actionId 动作ID
* @return 创建任务列表的JSON对象
*/
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject();
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// action_id
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// index
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
// entity_delta
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-create jsonobject");
}
return js;
}
/**
* 生成更新任务列表的JSON对象
* @param actionId 动作ID
* @return 更新任务列表的JSON对象
*/
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// action_id
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// id
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// entity_delta
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-update jsonobject");
}
return js;
}
/**
* 使用远程JSON对象设置任务列表内容
* @param js 远程JSON对象包含任务列表的数据
*/
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// name
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to get tasklist content from jsonobject");
}
}
}
/**
* 使用本地JSON对象设置任务列表内容
* @param js 本地JSON对象包含任务列表的数据
*/
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is available");
}
try {
JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
// 根据笔记类型设置任务列表名称
if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {
String name = folder.getString(NoteColumns.SNIPPET);
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name);
} else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER)
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT);
else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER)
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX
+ GTaskStringUtils.FOLDER_CALL_NOTE);
else
Log.e(TAG, "invalid system folder");
} else {
Log.e(TAG, "error type");
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
/**
* 获取本地JSON对象从内容中创建。
*
* @return 返回一个JSONObject其中包含了文件夹信息。
*/
public JSONObject getLocalJSONFromContent() {
// 尝试创建一个新的JSONObject
try {
JSONObject js = new JSONObject();
JSONObject folder = new JSONObject();
// 获取文件夹名称
String folderName = getName();
// 如果文件夹名称以MIUI_FOLDER_PREFFIX开头则去掉这个前缀
if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX))
folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(),
folderName.length());
// 将文件夹名称放入folder对象中
folder.put(NoteColumns.SNIPPET, folderName);
// 根据文件夹名称设置文件夹类型
if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT)
|| folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE))
folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
else
folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER);
// 将folder对象放入js对象中
js.put(GTaskStringUtils.META_HEAD_NOTE, folder);
// 返回js对象
return js;
} catch (JSONException e) {
// 如果发生异常记录错误并打印堆栈跟踪然后返回null
Log.e(TAG, e.toString());
e.printStackTrace();
return null;
}
}
/**
* 根据游标Cursor确定同步操作。
*
* @param c 游标对象,包含数据库列信息。
* @return 返回一个整数,表示同步操作类型。
*/
public int getSyncAction(Cursor c) {
try {
// 如果本地修改列为0表示没有本地更新
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
// 如果同步ID与最后修改时间相同表示两边都没有更新
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
return SYNC_ACTION_NONE;
} else {
// 应用远程更新到本地
return SYNC_ACTION_UPDATE_LOCAL;
}
} else {
// 验证gtask id是否匹配
if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) {
Log.e(TAG, "gtask id doesn't match");
return SYNC_ACTION_ERROR;
}
// 如果同步ID与最后修改时间相同表示只有本地修改
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
return SYNC_ACTION_UPDATE_REMOTE;
} else {
// 对于文件夹冲突,只应用本地修改
return SYNC_ACTION_UPDATE_REMOTE;
}
}
} catch (Exception e) {
// 如果发生异常,记录错误并打印堆栈跟踪
Log.e(TAG, e.toString());
e.printStackTrace();
}
// 发生错误时返回错误代码
return SYNC_ACTION_ERROR;
}
/**
* 获取子任务的数量。
*
* @return 返回子任务列表的大小。
*/
public int getChildTaskCount() {
return mChildren.size();
}
/**
* 添加一个子任务。
*
* @param task 要添加的子任务对象。
* @return 返回是否成功添加。
*/
public boolean addChildTask(Task task) {
boolean ret = false;
// 如果任务不为空且不在子任务列表中,则添加它
if (task != null && !mChildren.contains(task)) {
ret = mChildren.add(task);
// 如果添加成功,设置前一个兄弟节点和父节点
if (ret) {
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
.get(mChildren.size() - 1));
task.setParent(this);
}
}
return ret;
}
/**
* 在指定位置添加一个子任务。
*
* @param task 要添加的子任务对象。
* @param index 要插入的索引位置。
* @return 返回是否成功添加。
*/
public boolean addChildTask(Task task, int index) {
// 如果索引无效则记录错误并返回false
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "add child task: invalid index");
return false;
}
// 尝试在子任务列表中找到任务的位置
int pos = mChildren.indexOf(task);
// 如果任务不为空且不在子任务列表中,则添加它
if (task != null && pos == -1) {
mChildren.add(index, task);
// 更新任务列表
Task preTask = null;
Task afterTask = null;
if (index != 0)
preTask = mChildren.get(index - 1);
if (index != mChildren.size() - 1)
afterTask = mChildren.get(index + 1);
task.setPriorSibling(preTask);
if (afterTask != null)
afterTask.setPriorSibling(task);
}
return true;
}
/**
* 移除一个子任务。
*
* @param task 要移除的子任务对象。
* @return 返回是否成功移除。
*/
public boolean removeChildTask(Task task) {
boolean ret = false;
// 尝试在子任务列表中找到任务的索引
int index = mChildren.indexOf(task);
// 如果找到了任务,则移除它
if (index != -1) {
ret = mChildren.remove(task);
// 如果移除成功,重置前一个兄弟节点和父节点
if (ret) {
task.setPriorSibling(null);
task.setParent(null);
// 更新任务列表
if (index != mChildren.size()) {
mChildren.get(index).setPriorSibling(
index == 0 ? null : mChildren.get(index - 1));
}
}
}
return ret;
}
/**
* 移动一个子任务到指定位置。
*
* @param task 要移动的子任务对象。
* @param index 要移动到的索引位置。
* @return 返回是否成功移动。
*/
public boolean moveChildTask(Task task, int index) {
// 如果索引无效则记录错误并返回false
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
return false;
}
// 尝试在子任务列表中找到任务的位置
int pos = mChildren.indexOf(task);
// 如果任务不在列表中则记录错误并返回false
if (pos == -1) {
Log.e(TAG, "move child task: the task should in the list");
return false;
}
// 如果任务已经在指定位置则直接返回true
if (pos == index)
return true;
// 先移除任务,然后添加到新位置
return (removeChildTask(task) && addChildTask(task, index));
}
/**
* 根据GID查找子任务。
*
* @param gid 子任务的GID。
* @return 返回找到的子任务对象如果没有找到则返回null。
*/
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
// 如果找到匹配的GID则返回对应的子任务
if (t.getGid().equals(gid)) {
return t;
}
}
return null;
}
/**
* 根据索引获取子任务。
*
* @param index 子任务的索引。
* @return 返回子任务对象如果索引无效则返回null。
*/
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
/**
* 根据索引获取子任务。
*
* @param index 子任务的索引。
* @return 返回子任务对象如果索引无效则返回null。
*/
public Task getChildTaskByIndex(int index) {
// 如果索引无效则记录错误并返回null
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index");
return null;
}
return mChildren.get(index);
}
/**
* 根据GID获取子任务。
*
* @param gid 子任务的GID。
* @return 返回找到的子任务对象如果没有找到则返回null。
*/
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
// 如果找到匹配的GID则返回对应的子任务
if (task.getGid().equals(gid))
return task;
}
return null;
}
/**
* 获取所有子任务的列表。
*
* @return 返回子任务列表。
*/
public ArrayList<Task> getChildTaskList() {
return this.mChildren;
}
/**
* 设置任务的索引。
*
* @param index 任务的索引。
*/
public void setIndex(int index) {
this.mIndex = index;
}
/**
* 获取任务的索引。
*
* @return 返回任务的索引。
*/
public int getIndex() {
return this.mIndex;
}