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.
software/TaskList.txt

466 lines
17 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;
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;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
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 包含创建任务列表信息的JSONObject
*/
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
// 设置操作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 包含更新任务列表信息的JSONObject
*/
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
// 设置操作ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// id
// 设置任务列表的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) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 抛出自定义异常表示生成JSON对象失败
throw new ActionFailureException("fail to generate tasklist-update jsonobject");
}
return js; // 返回包含更新任务列表信息的JSONObject
}
/*
* 根据远程JSON对象设置任务列表的内容。
* @param js 包含任务列表信息的远程JSON对象
*/
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
// id
// 如果JSON对象中包含ID字段则设置任务列表的ID
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// last_modified
// 如果JSON对象中包含最后修改时间字段则设置任务列表的最后修改时间
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// name
// 如果JSON对象中包含名称字段则设置任务列表的名称
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 抛出自定义异常表示从JSON对象获取任务列表内容失败
throw new ActionFailureException("fail to get tasklist content from jsonobject");
}
}
}
/*
* 根据本地JSON对象设置任务列表的内容。
* @param js 包含任务列表信息的本地JSON对象
*/
public void setContentByLocalJSON(JSONObject js) {
// 检查JSON对象是否为空或是否包含必要的字段
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
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) {
// 如果是系统文件夹类型根据文件夹ID设置任务列表名称
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) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
/*
* 根据任务列表内容生成本地JSON对象。
* @return 包含任务列表内容的本地JSON对象如果发生错误则返回null
*/
public JSONObject getLocalJSONFromContent() {
try {
// 创建一个新的JSON对象
JSONObject js = new JSONObject();
JSONObject folder = new JSONObject();
// 获取任务列表的名称
String folderName = getName();
// 如果名称以GTaskStringUtils.MIUI_FOLDER_PREFFIX开头则去掉前缀
if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX))
folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(),
folderName.length());
// 设置文件夹名称
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);
// 将文件夹信息添加到JSON对象中
js.put(GTaskStringUtils.META_HEAD_NOTE, folder);
// 返回包含任务列表内容的本地JSON对象
return js;
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 如果发生错误返回null
return null;
}
}
/*
* 获取同步操作类型。
* @param c 包含本地笔记信息的Cursor对象
* @return 同步操作类型
*/
public int getSyncAction(Cursor c) {
try {
// 如果本地没有修改
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
// there is no local update
// 如果没有更新返回SYNC_ACTION_NONE
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// no update both side
return SYNC_ACTION_NONE;
} else {
// 应用远程更新到本地
// apply remote to local
return SYNC_ACTION_UPDATE_LOCAL;
}
} else {
// 验证Google任务ID是否匹配
// validate 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()) {
// local modification only
return SYNC_ACTION_UPDATE_REMOTE;
} else {
// for folder conflicts, just apply local modification
// 对于文件夹冲突,直接应用本地修改
return SYNC_ACTION_UPDATE_REMOTE;
}
}
} catch (Exception e) {
Log.e(TAG, e.toString());
// 捕获异常并记录错误日志
e.printStackTrace();
}
return SYNC_ACTION_ERROR; // 默认返回SYNC_ACTION_ERROR
}
/*
* 获取子任务的数量。
* @return 子任务的数量
*/
public int getChildTaskCount() {
return mChildren.size();
}
/*
* 添加子任务到任务列表中。
* @param task 要添加的子任务
* @return 如果成功添加子任务返回true否则返回false
*/
public boolean addChildTask(Task task) {
boolean ret = false;
// 检查任务是否为空且是否已存在于子任务列表中
if (task != null && !mChildren.contains(task)) {
// 将任务添加到子任务列表中
ret = mChildren.add(task);
if (ret) {
// need to set prior sibling and parent
// 需要设置前一个兄弟任务和父任务
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
.get(mChildren.size() - 1));
task.setParent(this);
}
}
return ret;
}
/*
* 在指定索引位置添加子任务到任务列表中。
* @param task 要添加的子任务
* @param index 要添加的索引位置
* @return 如果成功添加子任务返回true否则返回false
*/
public boolean addChildTask(Task task, int index) {
// 检查索引是否有效
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);
// update the task list
// 更新任务列表
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 如果成功移除子任务返回true否则返回false
*/
public boolean removeChildTask(Task task) {
boolean ret = false;
// 获取任务在子任务列表中的索引
int index = mChildren.indexOf(task);
if (index != -1) {
// 从子任务列表中移除任务
ret = mChildren.remove(task);
if (ret) {
// reset prior sibling and parent
// 重置任务的前一个兄弟任务和父任务
task.setPriorSibling(null);
task.setParent(null);
// update the task list
// 更新任务列表
if (index != mChildren.size()) {
// 如果移除的任务不是最后一个任务,则更新其后一个任务的前一个兄弟任务
mChildren.get(index).setPriorSibling(
index == 0 ? null : mChildren.get(index - 1));
}
}
}
return ret;
}
/*
* 将子任务移动到指定索引位置。
* @param task 要移动的子任务
* @param index 目标索引位置
* @return 如果成功移动子任务返回true否则返回false
*/
public boolean moveChildTask(Task task, int index) {
// 检查目标索引是否有效
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
return false;
}
// 获取任务在子任务列表中的当前位置
int pos = mChildren.indexOf(task);
if (pos == -1) {
Log.e(TAG, "move child task: the task should in the list");
return false;
}
// 如果目标索引与当前位置相同,则无需移动
if (pos == index)
return true;
// 先移除任务,然后将其添加到目标索引位置
return (removeChildTask(task) && addChildTask(task, index));
}
/*
* 根据任务的全局唯一标识符GID查找子任务。
* @param gid 任务的全局唯一标识符
* @return 找到的子任务如果未找到则返回null
*/
public Task findChildTaskByGid(String gid) {
// 遍历子任务列表
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
// 如果任务的GID与传入的GID匹配则返回该任务
if (t.getGid().equals(gid)) {
return t;
}
}
// 如果未找到匹配的任务返回null
return null;
}
/*
* 获取子任务在任务列表中的索引。
* @param task 子任务
* @return 子任务在任务列表中的索引,如果未找到则返回-1
*/
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
/*
* 根据索引获取子任务。
* @param index 子任务的索引
* @return 指定索引位置的子任务如果索引无效则返回null
*/
public Task getChildTaskByIndex(int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index");
return null;
}
return mChildren.get(index);
}
/*
* 根据任务的全局唯一标识符GID获取子任务。
* @param gid 任务的全局唯一标识符
* @return 找到的子任务如果未找到则返回null
*/
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
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;
}
}