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/WorkingNote.java

533 lines
19 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.model;
import android.appwidget.AppWidgetManager;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.CallNote;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.tool.ResourceParser.NoteBgResources;
/*
* WorkingNote 类用于管理笔记的创建、加载、保存和设置。
*/
public class WorkingNote {
// Note for the working note
// 当前工作笔记的 Note 对象
private Note mNote;
// Note Id
// 笔记的唯一标识符
private long mNoteId;
// Note content
// 笔记内容
private String mContent;
// Note mode
// 笔记模式
private int mMode;
// 提醒日期
private long mAlertDate;
// 修改日期
private long mModifiedDate;
// 背景颜色 ID
private int mBgColorId;
// 小部件 ID
private int mWidgetId;
// 小部件类型
private int mWidgetType;
// 文件夹 ID
private long mFolderId;
// 应用程序上下文
private Context mContext;
// 日志标签
private static final String TAG = "WorkingNote";
// 是否已删除
private boolean mIsDeleted;
// 笔记设置状态监听器
private NoteSettingChangedListener mNoteSettingStatusListener;
/*
* 数据查询投影。
* 该常量定义了在查询数据时需要返回的列。
*/
public static final String[] DATA_PROJECTION = new String[] {
DataColumns.ID, // 数据的唯一标识符
DataColumns.CONTENT, // 数据内容
DataColumns.MIME_TYPE,// 数据的 MIME 类型
DataColumns.DATA1,// 数据字段 1
DataColumns.DATA2, // 数据字段 2
DataColumns.DATA3, // 数据字段 3
DataColumns.DATA4, // 数据字段 4
};
/*
* 笔记查询投影。
* 该常量定义了在查询笔记时需要返回的列。
* @see NoteColumns
*/
public static final String[] NOTE_PROJECTION = new String[] {
NoteColumns.PARENT_ID, // 笔记的父 ID文件夹 ID
NoteColumns.ALERTED_DATE, // 笔记的提醒日期
NoteColumns.BG_COLOR_ID, // 笔记的背景颜色 ID
NoteColumns.WIDGET_ID, // 笔记的小部件 ID
NoteColumns.WIDGET_TYPE, // 笔记的小部件类型
NoteColumns.MODIFIED_DATE // 笔记的修改日期
};
// 数据列索引
private static final int DATA_ID_COLUMN = 0;
private static final int DATA_CONTENT_COLUMN = 1;
private static final int DATA_MIME_TYPE_COLUMN = 2;
private static final int DATA_MODE_COLUMN = 3;
// 笔记列索引
private static final int NOTE_PARENT_ID_COLUMN = 0;
private static final int NOTE_ALERTED_DATE_COLUMN = 1;
private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
private static final int NOTE_WIDGET_ID_COLUMN = 3;
private static final int NOTE_WIDGET_TYPE_COLUMN = 4;
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
// New note construct
/*
* 创建一个新的空笔记。
* 该构造函数用于初始化一个新的空笔记对象。
* @param context 应用程序上下文。
* @param folderId 文件夹 ID。
*/
private WorkingNote(Context context, long folderId) {
// 设置应用程序上下文
mContext = context;
mAlertDate = 0; // 初始化提醒日期为 0
mModifiedDate = System.currentTimeMillis();// 设置修改日期为当前时间
mFolderId = folderId;// 设置文件夹 ID
mNote = new Note();// 创建一个新的 Note 对象
mNoteId = 0;// 初始化笔记 ID 为 0
mIsDeleted = false;// 初始化删除状态为 false
mMode = 0;// 初始化笔记模式为 0
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;// 初始化小部件类型为无效类型
}
// Existing note construct
/*
* 加载现有的笔记
* 该构造函数用于加载现有的笔记对象。
* @param context 应用程序上下文。
* @param noteId 笔记的唯一标识符。
* @param folderId 文件夹 ID。
*/
private WorkingNote(Context context, long noteId, long folderId) {
mContext = context;// 设置应用程序上下文
mNoteId = noteId;// 设置笔记的唯一标识符
mFolderId = folderId;// 设置文件夹 ID
mIsDeleted = false;// 初始化删除状态为 false
mNote = new Note(); // 创建一个新的 Note 对象
loadNote();// 加载笔记数据
}
/*
* 加载笔记数据。
* 该方法用于从内容提供者中加载笔记数据,并将其设置到当前的 WorkingNote 对象中。
*/
private void loadNote() {
// 查询笔记数据
Cursor cursor = mContext.getContentResolver().query(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null,
null, null); // 检查游标是否为空
if (cursor != null) { // 移动游标到第一行
if (cursor.moveToFirst()) {
mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN); // 获取文件夹 ID
mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN); // 获取背景颜色 ID
mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);// 获取小部件 ID
mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN); // 获取小部件类型
mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);// 获取提醒日期
mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);// 获取修改日期
}
cursor.close(); // 关闭游标
} else { // 记录错误日志
Log.e(TAG, "No note with id:" + mNoteId);
// 抛出异常
throw new IllegalArgumentException("Unable to find note with id " + mNoteId);
}
loadNoteData();// 加载笔记数据
}
/*
* 加载笔记数据。
* 该方法用于从内容提供者中加载笔记的具体数据,并将其设置到当前的 WorkingNote 对象中。
*/
private void loadNoteData() {// 查询笔记数据
Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,
DataColumns.NOTE_ID + "=?", new String[] {
String.valueOf(mNoteId)
}, null); // 检查游标是否为空
if (cursor != null) { // 移动游标到第一行
if (cursor.moveToFirst()) {
do { // 获取数据的 MIME 类型
String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
if (DataConstants.NOTE.equals(type)) {// 根据 MIME 类型处理数据
mContent = cursor.getString(DATA_CONTENT_COLUMN); // 如果是文本笔记,获取内容和模式
mMode = cursor.getInt(DATA_MODE_COLUMN);
mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));
} else if (DataConstants.CALL_NOTE.equals(type)) {
mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN)); // 如果是通话笔记,获取通话数据 ID
} else {
Log.d(TAG, "Wrong note type with type:" + type); // 记录错误日志
}
} while (cursor.moveToNext());// 移动到下一行
}
cursor.close(); // 关闭游标
} else {
Log.e(TAG, "No data with id:" + mNoteId); // 记录错误日志
// 抛出异常
throw new IllegalArgumentException("Unable to find note's data with id " + mNoteId);
}
}
/*
* 创建一个新的空笔记。
* 该方法用于创建一个新的空笔记对象,并设置其背景颜色、小部件 ID 和小部件类型。
* @param context 应用程序上下文。
* @param folderId 文件夹 ID。
* @param widgetId 小部件 ID。
* @param widgetType 小部件类型。
* @param defaultBgColorId 默认背景颜色 ID。
* @return 新的 WorkingNote 对象。
*/
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
int widgetType, int defaultBgColorId) {
WorkingNote note = new WorkingNote(context, folderId);// 创建一个新的空笔记对象
note.setBgColorId(defaultBgColorId); // 设置背景颜色 ID
note.setWidgetId(widgetId);// 设置小部件 ID
note.setWidgetType(widgetType); // 设置小部件类型
return note;// 返回新的 WorkingNote 对象
}
/*
*加载现有的笔记。
* 该方法用于加载现有的笔记对象。
* @param context 应用程序上下文。
* @param id 笔记的唯一标识符。
* @return 加载的 WorkingNote 对象。
*/
public static WorkingNote load(Context context, long id) {
return new WorkingNote(context, id, 0); // 返回一个新的 WorkingNote 对象,使用指定的上下文和笔记 ID
}
/*
* 保存笔记。
* 该方法用于保存当前的笔记对象。如果笔记值得保存,则将其同步到数据库中,并更新小部件内容(如果存在小部件)。
* @return 如果保存成功,则返回 true否则返回 false。
*/
public synchronized boolean saveNote() {
if (isWorthSaving()) { // 检查笔记是否值得保存
if (!existInDatabase()) { // 如果笔记不存在于数据库中
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
// 获取新的笔记 ID
Log.e(TAG, "Create new note fail with id:" + mNoteId);// 记录错误日志
return false;
}
}
mNote.syncNote(mContext, mNoteId);// 同步笔记到数据库
/**
* Update widget content if there exist any widget of this note
* 如果存在该笔记的小部件,更新小部件内容。
*/
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE
&& mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onWidgetChanged();
}
return true;
} else {
return false;
}
}
/*
* 检查笔记是否存在于数据库中。
* 该方法用于检查当前笔记对象是否已经存在于数据库中。
* @return 如果笔记存在于数据库中,则返回 true否则返回 false。
*/
public boolean existInDatabase() {// 如果笔记 ID 大于 0表示笔记存在于数据库中
return mNoteId > 0;
}
/*
* 检查笔记是否值得保存。
* 该方法用于检查当前笔记对象是否值得保存。如果笔记已被删除、内容为空且不存在于数据库中,或者笔记存在于数据库中但没有本地修改,则不值得保存。
* @return 如果笔记值得保存,则返回 true否则返回 false。
*/
private boolean isWorthSaving() {
// 如果笔记已被删除,或者内容为空且不存在于数据库中,或者笔记存在于数据库中但没有本地修改,则不值得保存
if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent))
|| (existInDatabase() && !mNote.isLocalModified())) {
return false;
} else {
return true;
}
}
/*
* 设置笔记设置状态监听器。
* 该方法用于设置笔记设置状态的监听器,以便在笔记设置状态发生变化时通知监听器。
* @param l 笔记设置状态监听器。
*/
public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
mNoteSettingStatusListener = l; // 设置笔记设置状态监听器
}
/*
* 设置提醒日期。
* 该方法用于设置笔记的提醒日期。如果新的提醒日期与当前提醒日期不同,则更新提醒日期,并通知笔记设置状态监听器。
* @param date 提醒日期。
* @param set 是否设置提醒。
*/
public void setAlertDate(long date, boolean set) {
if (date != mAlertDate) { // 如果新的提醒日期与当前提醒日期不同
mAlertDate = date;// 更新提醒日期
mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));// 设置笔记的提醒日期
}
if (mNoteSettingStatusListener != null) {// 如果笔记设置状态监听器不为空
mNoteSettingStatusListener.onClockAlertChanged(date, set); // 通知笔记设置状态监听器提醒日期已更改
}
}
/*
* 标记笔记为已删除或未删除。
* 该方法用于标记笔记为已删除或未删除。如果笔记存在小部件,并且笔记设置状态监听器不为空,则通知笔记设置状态监听器小部件已更改。
* @param mark 是否标记为已删除。
*/
public void markDeleted(boolean mark) {
mIsDeleted = mark; // 标记笔记为已删除或未删除
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID // 如果笔记存在小部件,并且笔记设置状态监听器不为空
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {
// 通知笔记设置状态监听器小部件已更改
mNoteSettingStatusListener.onWidgetChanged();
}
}
/*
* 设置背景颜色 ID。
* 该方法用于设置笔记的背景颜色 ID。如果新的背景颜色 ID 与当前背景颜色 ID 不同,则更新背景颜色 ID并通知笔记设置状态监听器背景颜色已更改。
* @param id 背景颜色 ID。
*/
public void setBgColorId(int id) {
if (id != mBgColorId) { // 如果新的背景颜色 ID 与当前背景颜色 ID 不同
mBgColorId = id;// 更新背景颜色 ID
if (mNoteSettingStatusListener != null) { // 如果笔记设置状态监听器不为空
mNoteSettingStatusListener.onBackgroundColorChanged(); // 通知笔记设置状态监听器背景颜色已更改
}
mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id)); // 设置笔记的背景颜色 ID
}
}
/*
* 设置检查列表模式。
* 该方法用于设置笔记的检查列表模式。如果新的模式与当前模式不同,则更新模式,并通知笔记设置状态监听器检查列表模式已更改。
* @param mode 检查列表模式。
*/
public void setCheckListMode(int mode) {// 如果新的模式与当前模式不同
if (mMode != mode) { // 如果笔记设置状态监听器不为空
if (mNoteSettingStatusListener != null) { // 通知笔记设置状态监听器检查列表模式已更改
mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
}
mMode = mode;// 更新模式
mNote.setTextData(TextNote.MODE, String.valueOf(mMode)); // 设置笔记的检查列表模式
}
}
/*
* 设置小部件类型。
* 该方法用于设置笔记的小部件类型。如果新的类型与当前类型不同,则更新小部件类型,并将其保存到笔记数据中。
* @param type 小部件类型。
*/
public void setWidgetType(int type) { // 如果新的类型与当前类型不同
if (type != mWidgetType) { // 更新小部件类型
mWidgetType = type;
mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType)); // 设置笔记的小部件类型
}
}
/*
* 设置小部件 ID。
* 该方法用于设置笔记的小部件 ID。如果新的 ID 与当前 ID 不同,则更新小部件 ID并将其保存到笔记数据中。
* @param id 小部件 ID。
*/
public void setWidgetId(int id) { // 如果新的 ID 与当前 ID 不同
if (id != mWidgetId) { // 更新小部件 ID
mWidgetId = id;
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId)); // 设置笔记的小部件 ID
}
}
/*
* 设置工作文本。
* 该方法用于设置笔记的工作文本。如果新的文本与当前文本不同,则更新工作文本,并将其保存到笔记数据中。
* @param text 工作文本。
*/
public void setWorkingText(String text) { // 如果新的文本与当前文本不同
if (!TextUtils.equals(mContent, text)) { // 更新工作文本
mContent = text;
mNote.setTextData(DataColumns.CONTENT, mContent);// 设置笔记的工作文本
}
}
/*
* 将笔记转换为通话笔记。
* 该方法用于将笔记转换为通话笔记。它设置通话日期、电话号码和父文件夹 ID。
* @param phoneNumber 电话号码。
* @param callDate 通话日期。
*/
public void convertToCallNote(String phoneNumber, long callDate) {
mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate)); // 设置通话日期
mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);// 设置电话号码
mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER)); // 设置父文件夹 ID
}
/*
* 检查是否有提醒。
* 该方法用于检查笔记是否有提醒。如果提醒日期大于 0则表示有提醒。
* @return 如果有提醒,则返回 true否则返回 false。
*/
public boolean hasClockAlert() {
return (mAlertDate > 0 ? true : false);
}
/*
* 获取笔记内容。
* 该方法用于获取笔记的内容。
* @return 笔记内容。
*/
public String getContent() {
return mContent;
}
/*
* 获取提醒日期。
* 该方法用于获取笔记的提醒日期。
* @return 提醒日期。
*/
public long getAlertDate() {
return mAlertDate;
}
/*
* 获取修改日期。
* 该方法用于获取笔记的修改日期。
* @return 修改日期。
*/
public long getModifiedDate() {
return mModifiedDate;
}
/*
* 获取背景颜色资源 ID。
* 该方法用于获取笔记的背景颜色资源 ID。
* @return 背景颜色资源 ID。
*/
public int getBgColorResId() {
return NoteBgResources.getNoteBgResource(mBgColorId);
}
/*
* 获取背景颜色 ID。
* 该方法用于获取笔记的背景颜色 ID。
* @return 背景颜色 ID。
*/
public int getBgColorId() {
return mBgColorId;
}
/*
* 获取标题背景资源 ID。
* 该方法用于获取笔记的标题背景资源 ID。
* @return 标题背景资源 ID。
*/
public int getTitleBgResId() {
return NoteBgResources.getNoteTitleBgResource(mBgColorId);
}
/*
* 获取检查列表模式。
* 该方法用于获取笔记的检查列表模式。
* @return 检查列表模式。
*/
public int getCheckListMode() {
return mMode;
}
/*
* 获取笔记 ID。
* 该方法用于获取笔记的唯一标识符。
* @return 笔记 ID。
*/
public long getNoteId() {
return mNoteId;
}
/*
* 获取文件夹 ID。
* 该方法用于获取笔记所属的文件夹 ID。
* @return 文件夹 ID。
*/
public long getFolderId() {
return mFolderId;
}
/*
* 获取小部件 ID。
* 该方法用于获取笔记的小部件 ID。
* @return 小部件 ID。
*/
public int getWidgetId() {
return mWidgetId;
}
/*
* 获取小部件类型。
* 该方法用于获取笔记的小部件类型。
* @return 小部件类型。
*/
public int getWidgetType() {
return mWidgetType;
}
/*
* 笔记设置状态监听器接口。
* 该接口定义了笔记设置状态发生变化时的回调方法。
*/
public interface NoteSettingChangedListener {
/**
* Called when the background color of current note has just changed
* 当当前笔记的背景颜色发生变化时调用。
*/
void onBackgroundColorChanged();
/**
* Called when user set clock
* 当用户设置提醒时调用。
* @param date 提醒日期。
* @param set 是否设置提醒
*/
void onClockAlertChanged(long date, boolean set);
/**
* Call when user create note from widget
* 当用户从小部件创建笔记时调用。
*/
void onWidgetChanged();
/**
* Call when switch between check list mode and normal mode
* @param oldMode is previous mode before change
* @param newMode is new mode
* 当用户在检查列表模式和普通模式之间切换时调用。
* @param oldMode 之前的模式。
* @param newMode 新的模式。
*/
void onCheckListModeChanged(int oldMode, int newMode);
}
}