forked from poz2c78vw/read
Compare commits
48 Commits
Binary file not shown.
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* 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.appwidget.AppWidgetManager; // 处理小部件的类
|
||||
import android.content.ContentResolver; // 用于访问内容提供者的类
|
||||
import android.content.ContentValues; // 用于存储内容数据的类
|
||||
import android.content.Context; // Android上下文类
|
||||
import android.database.Cursor; // 数据库操作的游标类
|
||||
import android.net.Uri; // URI的类
|
||||
import android.util.Log; // 日志记录类
|
||||
|
||||
// 导入笔记和相关数据列的类
|
||||
import net.micode.notes.data.Notes;
|
||||
import net.micode.notes.data.Notes.DataColumns;
|
||||
import net.micode.notes.data.Notes.NoteColumns;
|
||||
import net.micode.notes.gtask.exception.ActionFailureException; // 自定义异常类
|
||||
import net.micode.notes.tool.GTaskStringUtils; // 字符串工具类
|
||||
import net.micode.notes.tool.ResourceParser; // 资源解析工具类
|
||||
|
||||
import org.json.JSONArray; // JSON数组类
|
||||
import org.json.JSONException; // JSON异常类
|
||||
import org.json.JSONObject; // JSON对象类
|
||||
|
||||
import java.util.ArrayList; // 动态数组类
|
||||
|
||||
// Task类用于表示一个任务
|
||||
public class Task {
|
||||
private static final String TAG = Task.class.getSimpleName(); // 日志标识
|
||||
|
||||
private boolean mCompleted; // 标识任务是否已完成
|
||||
private String mNotes; // 任务的备注
|
||||
private Task mPriorSibling; // 优先兄弟任务
|
||||
private TaskList mParent; // 父任务列表
|
||||
private JSONObject mMetaInfo; // 任务的元信息
|
||||
|
||||
// 构造函数
|
||||
public Task() {
|
||||
super(); // 调用父类构造函数
|
||||
mCompleted = false; // 默认任务未完成
|
||||
mNotes = null; // 备注初始化为null
|
||||
mPriorSibling = null; // 优先兄弟任务初始化为null
|
||||
mParent = null; // 父任务列表初始化为null
|
||||
mMetaInfo = null; // 元信息初始化为null
|
||||
}
|
||||
|
||||
// 获取创建操作的JSON对象
|
||||
public JSONObject getCreateAction(int actionId) {
|
||||
JSONObject js = new JSONObject(); // 创建新的JSON对象
|
||||
|
||||
try {
|
||||
// 设置操作类型
|
||||
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
|
||||
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
|
||||
|
||||
// 设置操作ID
|
||||
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
|
||||
|
||||
// 设置索引
|
||||
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this));
|
||||
|
||||
// 创建实体增量对象
|
||||
JSONObject entity = new JSONObject();
|
||||
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 设置任务名称
|
||||
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); // 创建者ID
|
||||
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
|
||||
GTaskStringUtils.GTASK_JSON_TYPE_TASK); // 设置实体类型
|
||||
if (getNotes() != null) {
|
||||
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); // 设置任务备注
|
||||
}
|
||||
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 将增量对象添加至主对象
|
||||
|
||||
// 设置父任务ID
|
||||
js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid());
|
||||
|
||||
// 设置目标父级类型
|
||||
js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE,
|
||||
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
|
||||
|
||||
// 设置列表ID
|
||||
js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid());
|
||||
|
||||
// 设置优先兄弟任务ID
|
||||
if (mPriorSibling != null) {
|
||||
js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid());
|
||||
}
|
||||
|
||||
} catch (JSONException e) { // 捕获JSON异常
|
||||
Log.e(TAG, e.toString()); // 输出错误日志
|
||||
e.printStackTrace(); // 打印堆栈信息
|
||||
throw new ActionFailureException("fail to generate task-create jsonobject"); // 抛出异常
|
||||
}
|
||||
|
||||
return js; // 返回生成的JSON对象
|
||||
}
|
||||
|
||||
// 获取更新操作的JSON对象
|
||||
public JSONObject getUpdateAction(int actionId) {
|
||||
JSONObject js = new JSONObject(); // 创建新的JSON对象
|
||||
|
||||
try {
|
||||
// 设置操作类型
|
||||
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
|
||||
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
|
||||
|
||||
// 设置操作ID
|
||||
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
|
||||
|
||||
// 设置任务ID
|
||||
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
|
||||
|
||||
// 创建实体增量对象
|
||||
JSONObject entity = new JSONObject();
|
||||
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 设置任务名称
|
||||
if (getNotes() != null) {
|
||||
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); // 设置任务备注
|
||||
}
|
||||
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(); // 打印堆栈信息
|
||||
throw new ActionFailureException("fail to generate task-update jsonobject"); // 抛出异常
|
||||
}
|
||||
|
||||
return js; // 返回生成的JSON对象
|
||||
}
|
||||
|
||||
// 根据远程JSON设置任务内容
|
||||
public void setContentByRemoteJSON(JSONObject js) {
|
||||
if (js != null) { // 如果JSON对象不为空
|
||||
try {
|
||||
// 设置任务ID
|
||||
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
|
||||
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
|
||||
}
|
||||
|
||||
// 设置最后修改时间
|
||||
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
|
||||
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
|
||||
}
|
||||
|
||||
// 设置任务名称
|
||||
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
|
||||
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
|
||||
}
|
||||
|
||||
// 设置任务备注
|
||||
if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
|
||||
setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES));
|
||||
}
|
||||
|
||||
// 设置删除标志
|
||||
if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
|
||||
setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED));
|
||||
}
|
||||
|
||||
// 设置完成状态
|
||||
if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) {
|
||||
setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED));
|
||||
}
|
||||
} catch (JSONException e) { // 捕获JSON异常
|
||||
Log.e(TAG, e.toString()); // 输出错误日志
|
||||
e.printStackTrace(); // 打印堆栈信息
|
||||
throw new ActionFailureException("fail to get task content from jsonobject"); // 抛出异常
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据本地JSON设置任务内容
|
||||
public void setContentByLocalJSON(JSONObject js) {
|
||||
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|
||||
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) { // 检查必需字段
|
||||
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); // 无数据警告
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取笔记对象
|
||||
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); // 获取数据数组
|
||||
|
||||
if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) { // 检查任务类型
|
||||
Log.e(TAG, "invalid type"); // 输出错误日志
|
||||
return; // 返回
|
||||
}
|
||||
|
||||
// 遍历数据数组
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject data = dataArray.getJSONObject(i); // 获取每个数据对象
|
||||
if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) { // 检查MIME类型
|
||||
setName(data.getString(DataColumns.CONTENT)); // 设置任务名称
|
||||
break; // 退出循环
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JSONException e) { // 捕获JSON异常
|
||||
Log.e(TAG, e.toString()); // 输出错误日志
|
||||
e.printStackTrace(); // 打印堆栈信息
|
||||
}
|
||||
}
|
||||
|
||||
// 从内容获取本地JSON
|
||||
public JSONObject getLocalJSONFromContent() {
|
||||
String name = getName(); // 获取任务名称
|
||||
try {
|
||||
if (mMetaInfo == null) { // 如果元信息为null
|
||||
// 新任务从网络创建
|
||||
if (name == null) { // 如果名称为空
|
||||
Log.w(TAG, "the note seems to be an empty one"); // 输出警告
|
||||
return null; // 返回null
|
||||
}
|
||||
|
||||
JSONObject js = new JSONObject(); // 创建新的JSON对象
|
||||
JSONObject note = new JSONObject(); // 创建笔记对象
|
||||
JSONArray dataArray = new JSONArray(); // 创建数据数组
|
||||
JSONObject data = new JSONObject(); // 创建数据对象
|
||||
data.put(DataColumns.CONTENT, name); // 设置内容
|
||||
dataArray.put(data); // 添加数据对象到数组
|
||||
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray); // 将数据数组添加到主对象
|
||||
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); // 设置任务类型
|
||||
js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 将笔记对象添加到主对象
|
||||
return js; // 返回生成的JSON对象
|
||||
} else {
|
||||
// 已同步的任务
|
||||
JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取元信息中的笔记对象
|
||||
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA); // 获取数据数组
|
||||
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject data = dataArray.getJSONObject(i); // 获取数据对象
|
||||
if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
|
||||
data.put(DataColumns.CONTENT, getName()); // 更新内容
|
||||
break; // 退出循环
|
||||
}
|
||||
}
|
||||
|
||||
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); // 确保类型为笔记
|
||||
return mMetaInfo; // 返回元信息
|
||||
}
|
||||
} catch (JSONException e) { // 捕获JSON异常
|
||||
Log.e(TAG, e.toString()); // 输出错误日志
|
||||
e.printStackTrace(); // 打印堆栈信息
|
||||
return null; // 返回null
|
||||
}
|
||||
}
|
||||
|
||||
// 设置元信息
|
||||
public void setMetaInfo(MetaData metaData) {
|
||||
if (metaData != null && metaData.getNotes() != null) { // 检查元数据及笔记是否为空
|
||||
try {
|
||||
mMetaInfo = new JSONObject(metaData.getNotes()); // 从元数据中获取笔记信息
|
||||
} catch (JSONException e) { // 捕获JSON异常
|
||||
Log.w(TAG, e.toString()); // 输出警告日志
|
||||
mMetaInfo = null; // 将元信息设为null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取同步操作
|
||||
public int getSyncAction(Cursor c) {
|
||||
try {
|
||||
JSONObject noteInfo = null; // 笔记信息对象
|
||||
// 检查元信息是否存在
|
||||
if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
|
||||
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取笔记信息
|
||||
}
|
||||
|
||||
if (noteInfo == null) { // 如果笔记信息为空
|
||||
Log.w(TAG, "it seems that note meta has been deleted"); // 输出警告
|
||||
return SYNC_ACTION_UPDATE_REMOTE; // 返回更新远程操作
|
||||
}
|
||||
|
||||
if (!noteInfo.has(NoteColumns.ID)) { // 如果笔记ID不存在
|
||||
Log.w(TAG, "remote note id seems to be deleted"); // 输出警告
|
||||
return SYNC_ACTION_UPDATE_LOCAL; // 返回更新本地操作
|
||||
}
|
||||
|
||||
// 验证笔记ID
|
||||
if (c.getLong(SqlNote.ID_COLUMN) != noteInfo.getLong(NoteColumns.ID)) {
|
||||
Log.w(TAG, "note id doesn't match"); // 输出警告
|
||||
return SYNC_ACTION_UPDATE_LOCAL; // 返回更新本地操作
|
||||
}
|
||||
|
||||
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; // 返回错误操作
|
||||
}
|
||||
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
|
||||
// 仅本地修改
|
||||
return SYNC_ACTION_UPDATE_REMOTE; // 返回更新远程操作
|
||||
} else {
|
||||
return SYNC_ACTION_UPDATE_CONFLICT; // 返回更新冲突操作
|
||||
}
|
||||
}
|
||||
} catch (Exception e) { // 捕获所有异常
|
||||
Log.e(TAG, e.toString()); // 输出错误日志
|
||||
e.printStackTrace(); // 打印堆栈信息
|
||||
}
|
||||
|
||||
return SYNC_ACTION_ERROR; // 返回错误操作
|
||||
}
|
||||
|
||||
// 判断任务是否值得保存
|
||||
public boolean isWorthSaving() {
|
||||
return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
|
||||
|| (getNotes() != null && getNotes().trim().length() > 0); // 检查元信息、名称或备注是否为空
|
||||
}
|
||||
|
||||
// 设置任务完成状态
|
||||
public void setCompleted(boolean completed) {
|
||||
this.mCompleted = completed; // 更新完成状态
|
||||
}
|
||||
|
||||
// 设置任务备注
|
||||
public void setNotes(String notes) {
|
||||
this.mNotes = notes; // 更新备注
|
||||
}
|
||||
|
||||
// 设置优先兄弟任务
|
||||
public void setPriorSibling(Task priorSibling) {
|
||||
this.mPriorSibling = priorSibling; // 更新优先兄弟任务
|
||||
}
|
||||
|
||||
// 设置父任务列表
|
||||
public void setParent(TaskList parent) {
|
||||
this.mParent = parent; // 更新父任务列表
|
||||
}
|
||||
|
||||
// 获取完成状态
|
||||
public boolean getCompleted() {
|
||||
return this.mCompleted; // 返回完成状态
|
||||
}
|
||||
|
||||
// 获取备注
|
||||
public String getNotes() {
|
||||
return this.mNotes; // 返回备注
|
||||
}
|
||||
|
||||
// 获取优先兄弟任务
|
||||
public Task getPriorSibling() {
|
||||
return this.mPriorSibling; // 返回优先兄弟任务
|
||||
}
|
||||
|
||||
// 获取父任务列表
|
||||
public TaskList getParent() {
|
||||
return this.mParent; // 返回父任务列表
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.ui; // 定义包名
|
||||
|
||||
import android.content.Context; // 导入上下文类
|
||||
import android.view.Menu; // 导入菜单类
|
||||
import android.view.MenuItem; // 导入菜单项类
|
||||
import android.view.View; // 导入视图类
|
||||
import android.view.View.OnClickListener; // 导入点击监听器接口
|
||||
import android.widget.Button; // 导入按钮类
|
||||
import android.widget.PopupMenu; // 导入弹出菜单类
|
||||
import android.widget.PopupMenu.OnMenuItemClickListener; // 导入弹出菜单项点击监听器接口
|
||||
|
||||
import net.micode.notes.R; // 导入资源类
|
||||
|
||||
public class DropdownMenu { // 定义下拉菜单类
|
||||
private Button mButton; // 存储按钮对象
|
||||
private PopupMenu mPopupMenu; // 存储弹出菜单对象
|
||||
private Menu mMenu; // 存储菜单对象
|
||||
|
||||
// 构造函数,接受上下文、按钮和菜单资源 ID
|
||||
public DropdownMenu(Context context, Button button, int menuId) {
|
||||
mButton = button; // 初始化按钮
|
||||
mButton.setBackgroundResource(R.drawable.dropdown_icon); // 设置按钮背景为下拉图标
|
||||
mPopupMenu = new PopupMenu(context, mButton); // 创建弹出菜单,依附于指定按钮
|
||||
mMenu = mPopupMenu.getMenu(); // 获取弹出菜单的菜单对象
|
||||
mPopupMenu.getMenuInflater().inflate(menuId, mMenu); // 将指定的菜单资源填充到菜单对象中
|
||||
mButton.setOnClickListener(new OnClickListener() { // 设置按钮点击监听器
|
||||
public void onClick(View v) {
|
||||
mPopupMenu.show(); // 显示弹出菜单
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 设置下拉菜单项点击监听器
|
||||
public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) {
|
||||
if (mPopupMenu != null) { // 如果弹出菜单不为空
|
||||
mPopupMenu.setOnMenuItemClickListener(listener); // 设置菜单项点击监听器
|
||||
}
|
||||
}
|
||||
|
||||
// 根据 ID 查找菜单项
|
||||
public MenuItem findItem(int id) {
|
||||
return mMenu.findItem(id); // 根据 ID 返回菜单项
|
||||
}
|
||||
|
||||
// 设置按钮的标题
|
||||
public void setTitle(CharSequence title) {
|
||||
mButton.setText(title); // 更新按钮文本为给定的标题
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.ui; // 定义包名
|
||||
|
||||
import android.content.Context; // 导入上下文类
|
||||
import android.database.Cursor; // 导入游标类
|
||||
import android.view.View; // 导入视图类
|
||||
import android.view.ViewGroup; // 导入视图组类
|
||||
import android.widget.CursorAdapter; // 导入游标适配器类
|
||||
import android.widget.LinearLayout; // 导入线性布局类
|
||||
import android.widget.TextView; // 导入文本视图类
|
||||
|
||||
import net.micode.notes.R; // 导入资源类
|
||||
import net.micode.notes.data.Notes; // 导入笔记数据类
|
||||
import net.micode.notes.data.Notes.NoteColumns; // 导入笔记列类
|
||||
|
||||
public class FoldersListAdapter extends CursorAdapter { // 定义文件夹列表适配器类,继承自 CursorAdapter
|
||||
public static final String [] PROJECTION = { // 定义需要查询的字段数组
|
||||
NoteColumns.ID, // 笔记 ID 列
|
||||
NoteColumns.SNIPPET // 笔记摘要列
|
||||
};
|
||||
|
||||
public static final int ID_COLUMN = 0; // ID 列索引
|
||||
public static final int NAME_COLUMN = 1; // 名称列索引
|
||||
|
||||
// 构造函数,接受上下文和游标作为参数
|
||||
public FoldersListAdapter(Context context, Cursor c) {
|
||||
super(context, c); // 调用父类构造函数
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
// 创建新的视图
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
return new FolderListItem(context); // 返回新的文件夹列表项视图
|
||||
}
|
||||
|
||||
// 绑定视图与数据
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
if (view instanceof FolderListItem) { // 如果视图是 FolderListItem 的实例
|
||||
// 获取文件夹名称,判断是否为根文件夹
|
||||
String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
|
||||
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
|
||||
((FolderListItem) view).bind(folderName); // 绑定文件夹名称到视图
|
||||
}
|
||||
}
|
||||
|
||||
// 根据位置获取文件夹名称
|
||||
public String getFolderName(Context context, int position) {
|
||||
Cursor cursor = (Cursor) getItem(position); // 获取指定位置的游标
|
||||
// 判断是否为根文件夹,返回相应的名称
|
||||
return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
|
||||
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
|
||||
}
|
||||
|
||||
// 内部类,表示文件夹列表项
|
||||
private class FolderListItem extends LinearLayout { // 继承自 LinearLayout
|
||||
private TextView mName; // 存储文件夹名称的文本视图
|
||||
|
||||
// 构造函数,接受上下文作为参数
|
||||
public FolderListItem(Context context) {
|
||||
super(context); // 调用父类构造函数
|
||||
inflate(context, R.layout.folder_list_item, this); // 加载布局文件
|
||||
mName = (TextView) findViewById(R.id.tv_folder_name); // 初始化文件夹名称文本视图
|
||||
}
|
||||
|
||||
// 绑定文件夹名称到文本视图
|
||||
public void bind(String name) {
|
||||
mName.setText(name); // 设置文本视图的文本为文件夹名称
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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.ui; // 定义包名
|
||||
|
||||
import android.content.Context; // 导入Context类
|
||||
import android.database.Cursor; // 导入Cursor类
|
||||
import android.text.TextUtils; // 导入TextUtils类
|
||||
|
||||
import net.micode.notes.data.Contact; // 导入Contact类
|
||||
import net.micode.notes.data.Notes; // 导入Notes类
|
||||
import net.micode.notes.data.Notes.NoteColumns; // 导入Notes列类
|
||||
import net.micode.notes.tool.DataUtils; // 导入数据工具类
|
||||
|
||||
public class NoteItemData { // 定义笔记项数据类
|
||||
static final String [] PROJECTION = new String [] { // 定义要查询的列数组
|
||||
NoteColumns.ID, // 笔记ID列
|
||||
NoteColumns.ALERTED_DATE, // 警报日期列
|
||||
NoteColumns.BG_COLOR_ID, // 背景颜色ID列
|
||||
NoteColumns.CREATED_DATE, // 创建日期列
|
||||
NoteColumns.HAS_ATTACHMENT, // 是否有附件列
|
||||
NoteColumns.MODIFIED_DATE, // 修改日期列
|
||||
NoteColumns.NOTES_COUNT, // 笔记数量列
|
||||
NoteColumns.PARENT_ID, // 父级ID列
|
||||
NoteColumns.SNIPPET, // 摘要列
|
||||
NoteColumns.TYPE, // 类型列
|
||||
NoteColumns.WIDGET_ID, // 小部件ID列
|
||||
NoteColumns.WIDGET_TYPE, // 小部件类型列
|
||||
};
|
||||
|
||||
private static final int ID_COLUMN = 0; // ID列索引
|
||||
private static final int ALERTED_DATE_COLUMN = 1; // 警报日期列索引
|
||||
private static final int BG_COLOR_ID_COLUMN = 2; // 背景颜色ID列索引
|
||||
private static final int CREATED_DATE_COLUMN = 3; // 创建日期列索引
|
||||
private static final int HAS_ATTACHMENT_COLUMN = 4; // 附件列索引
|
||||
private static final int MODIFIED_DATE_COLUMN = 5; // 修改日期列索引
|
||||
private static final int NOTES_COUNT_COLUMN = 6; // 笔记数量列索引
|
||||
private static final int PARENT_ID_COLUMN = 7; // 父级ID列索引
|
||||
private static final int SNIPPET_COLUMN = 8; // 摘要列索引
|
||||
private static final int TYPE_COLUMN = 9; // 类型列索引
|
||||
private static final int WIDGET_ID_COLUMN = 10; // 小部件ID列索引
|
||||
private static final int WIDGET_TYPE_COLUMN = 11; // 小部件类型列索引
|
||||
|
||||
private long mId; // 笔记ID
|
||||
private long mAlertDate; // 警报日期
|
||||
private int mBgColorId; // 背景颜色ID
|
||||
private long mCreatedDate; // 创建日期
|
||||
private boolean mHasAttachment; // 是否有附件
|
||||
private long mModifiedDate; // 修改日期
|
||||
private int mNotesCount; // 笔记数量
|
||||
private long mParentId; // 父级ID
|
||||
private String mSnippet; // 摘要
|
||||
private int mType; // 笔记类型
|
||||
private int mWidgetId; // 小部件ID
|
||||
private int mWidgetType; // 小部件类型
|
||||
private String mName; // 联系人名称
|
||||
private String mPhoneNumber; // 联系电话号码
|
||||
|
||||
// 用于记录该笔记在列表中的位置信息
|
||||
private boolean mIsLastItem; // 是否为最后一项
|
||||
private boolean mIsFirstItem; // 是否为第一项
|
||||
private boolean mIsOnlyOneItem; // 是否为唯一一项
|
||||
private boolean mIsOneNoteFollowingFolder; // 是否为文件夹下唯一笔记
|
||||
private boolean mIsMultiNotesFollowingFolder; // 是否有多个笔记在文件夹下
|
||||
|
||||
// 构造函数,接收上下文和游标作为参数
|
||||
public NoteItemData(Context context, Cursor cursor) {
|
||||
mId = cursor.getLong(ID_COLUMN); // 从游标中获取笔记ID
|
||||
mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN); // 从游标中获取警报日期
|
||||
mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN); // 从游标中获取背景颜色ID
|
||||
mCreatedDate = cursor.getLong(CREATED_DATE_COLUMN); // 从游标中获取创建日期
|
||||
mHasAttachment = (cursor.getInt(HAS_ATTACHMENT_COLUMN) > 0) ? true : false; // 根据游标中的信息判断是否有附件
|
||||
mModifiedDate = cursor.getLong(MODIFIED_DATE_COLUMN); // 从游标中获取修改日期
|
||||
mNotesCount = cursor.getInt(NOTES_COUNT_COLUMN); // 从游标中获取笔记数量
|
||||
mParentId = cursor.getLong(PARENT_ID_COLUMN); // 从游标中获取父级ID
|
||||
mSnippet = cursor.getString(SNIPPET_COLUMN); // 从游标中获取摘要
|
||||
mSnippet = mSnippet.replace(NoteEditActivity.TAG_CHECKED, "").replace( // 清除已勾选标记
|
||||
NoteEditActivity.TAG_UNCHECKED, "");
|
||||
mType = cursor.getInt(TYPE_COLUMN); // 从游标中获取笔记类型
|
||||
mWidgetId = cursor.getInt(WIDGET_ID_COLUMN); // 从游标中获取小部件ID
|
||||
mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN); // 从游标中获取小部件类型
|
||||
|
||||
mPhoneNumber = ""; // 初始化联系电话为空
|
||||
if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { // 如果父级ID为通话记录文件夹
|
||||
mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId); // 根据笔记ID获取通话记录电话号码
|
||||
if (!TextUtils.isEmpty(mPhoneNumber)) { // 如果电话号码不为空
|
||||
mName = Contact.getContact(context, mPhoneNumber); // 获取联系人的名称
|
||||
if (mName == null) { // 如果没有联系人名称
|
||||
mName = mPhoneNumber; // 将名称设置为电话号码
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mName == null) { // 如果名称还是为null
|
||||
mName = ""; // 设置为空字符串
|
||||
}
|
||||
checkPostion(cursor); // 检查位置信息
|
||||
}
|
||||
|
||||
private void checkPostion(Cursor cursor) { // 检查当前项目在游标中的位置信息
|
||||
mIsLastItem = cursor.isLast(); // 判断是否为最后一项
|
||||
mIsFirstItem = cursor.isFirst(); // 判断是否为第一项
|
||||
mIsOnlyOneItem = (cursor.getCount() == 1); // 判断是否为唯一一项
|
||||
mIsMultiNotesFollowingFolder = false; // 初始化为false
|
||||
mIsOneNoteFollowingFolder = false; // 初始化为false
|
||||
|
||||
if (mType == Notes.TYPE_NOTE && !mIsFirstItem) { // 如果当前类型为笔记且不是第一项
|
||||
int position = cursor.getPosition(); // 获取当前游标位置
|
||||
if (cursor.moveToPrevious()) { // 移动游标到上一项
|
||||
// 如果上一项是文件夹或系统类型
|
||||
if (cursor.getInt(TYPE_COLUMN) == Notes.TYPE_FOLDER
|
||||
|| cursor.getInt(TYPE_COLUMN) == Notes.TYPE_SYSTEM) {
|
||||
if (cursor.getCount() > (position + 1)) { // 如果游标数量大于当前位置加1
|
||||
mIsMultiNotesFollowingFolder = true; // 模式是多个笔记在文件夹下
|
||||
} else {
|
||||
mIsOneNoteFollowingFolder = true; // 模式是唯一笔记在文件夹下
|
||||
}
|
||||
}
|
||||
if (!cursor.moveToNext()) { // 移动回当前游标位置失败
|
||||
throw new IllegalStateException("cursor move to previous but can't move back"); // 抛出异常
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOneFollowingFolder() { // 判断是否为唯一笔记在文件夹下
|
||||
return mIsOneNoteFollowingFolder; // 返回结果
|
||||
}
|
||||
|
||||
public boolean isMultiFollowingFolder() { // 判断是否有多个笔记在文件夹下
|
||||
return mIsMultiNotesFollowingFolder; // 返回结果
|
||||
}
|
||||
|
||||
public boolean isLast() { // 判断是否为最后一项
|
||||
return mIsLastItem; // 返回结果
|
||||
}
|
||||
|
||||
public String getCallName() { // 获取通话记录联系人名称
|
||||
return mName; // 返回联系人名称
|
||||
}
|
||||
|
||||
public boolean isFirst() { // 判断是否为第一项
|
||||
return mIsFirstItem; // 返回结果
|
||||
}
|
||||
|
||||
public boolean isSingle() { // 判断是否为唯一一项
|
||||
return mIsOnlyOneItem; // 返回结果
|
||||
}
|
||||
|
||||
public long getId() { // 获取笔记ID
|
||||
return mId; // 返回笔记ID
|
||||
}
|
||||
|
||||
public long getAlertDate() { // 获取警报日期
|
||||
return mAlertDate; // 返回警报日期
|
||||
}
|
||||
|
||||
public long getCreatedDate() { // 获取创建日期
|
||||
return mCreatedDate; // 返回创建日期
|
||||
}
|
||||
|
||||
public boolean hasAttachment() { // 判断是否有附件
|
||||
return mHasAttachment; // 返回结果
|
||||
}
|
||||
|
||||
public long getModifiedDate() { // 获取修改日期
|
||||
return mModifiedDate; // 返回修改日期
|
||||
}
|
||||
|
||||
public int getBgColorId() { // 获取背景颜色ID
|
||||
return mBgColorId; // 返回背景颜色ID
|
||||
}
|
||||
|
||||
public long getParentId() { // 获取父级ID
|
||||
return mParentId; // 返回父级ID
|
||||
}
|
||||
|
||||
public int getNotesCount() { // 获取笔记数量
|
||||
return mNotesCount; // 返回笔记数量
|
||||
}
|
||||
|
||||
public long getFolderId () { // 获取文件夹ID
|
||||
return mParentId; // 返回父级ID
|
||||
}
|
||||
|
||||
public int getType() { // 获取笔记类型
|
||||
return mType; // 返回笔记类型
|
||||
}
|
||||
|
||||
public int getWidgetType() { // 获取小部件类型
|
||||
return mWidgetType; // 返回小部件类型
|
||||
}
|
||||
|
||||
public int getWidgetId() { // 获取小部件ID
|
||||
return mWidgetId; // 返回小部件ID
|
||||
}
|
||||
|
||||
public String getSnippet() { // 获取摘要
|
||||
return mSnippet; // 返回摘要
|
||||
}
|
||||
|
||||
public boolean hasAlert() { // 判断是否有警报
|
||||
return (mAlertDate > 0); // 根据警报日期判断
|
||||
}
|
||||
|
||||
public boolean isCallRecord() { // 判断是否为通话记录笔记
|
||||
return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber)); // 如果父ID为通话记录且电话号码不为空
|
||||
}
|
||||
|
||||
public static int getNoteType(Cursor cursor) { // 根据游标获取笔记类型
|
||||
return cursor.getInt(TYPE_COLUMN); // 返回笔记类型
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue