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.
xiaomibianqian/src/main/java/net/micode/notes/model/WorkingNote.java

648 lines
21 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.EncryptionUtils;
import net.micode.notes.tool.ResourceParser.NoteBgResources;
/**
* WorkingNote 类用于表示正在编辑或查看的便签对象
* 负责加载、保存和管理便签数据,包括内容、标题、提醒日期等属性
*/
public class WorkingNote {
/** 便签对象,用于存储便签的详细数据 */
private Note mNote;
/** 便签 ID */
private long mNoteId;
/** 便签内容 */
private String mContent;
/** 便签标题 */
private String mTitle;
/** 便签模式(普通模式或 checklist 模式) */
private int mMode;
/** 提醒日期 */
private long mAlertDate;
/** 修改日期 */
private long mModifiedDate;
/** 背景颜色 ID */
private int mBgColorId;
/** 小组件 ID */
private int mWidgetId;
/** 小组件类型 */
private int mWidgetType;
/** 是否置顶 */
private boolean mPinned;
/** 是否加密 */
private boolean mEncrypted;
/** 密码哈希值 */
private String mPasswordHash;
/** 文件夹 ID */
private long mFolderId;
/** 上下文对象 */
private Context mContext;
/** 日志标签 */
private static final String TAG = "WorkingNote";
/** 是否已删除 */
private boolean mIsDeleted;
/** 便签设置变更监听器 */
private NoteSettingChangedListener mNoteSettingStatusListener;
/**
* 数据查询投影,用于查询便签数据
* 包含 ID、内容、MIME 类型、DATA1-DATA4 字段
*/
public static final String[] DATA_PROJECTION = new String[] {
DataColumns.ID,
DataColumns.CONTENT,
DataColumns.MIME_TYPE,
DataColumns.DATA1,
DataColumns.DATA2,
DataColumns.DATA3,
DataColumns.DATA4,
};
/**
* 便签查询投影,用于查询便签基本信息
* 包含父文件夹 ID、提醒日期、背景颜色、小组件信息等
*/
public static final String[] NOTE_PROJECTION = new String[] {
NoteColumns.PARENT_ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.MODIFIED_DATE,
NoteColumns.PINNED,
NoteColumns.ENCRYPTED,
NoteColumns.PASSWORD_HASH
};
/** 数据列索引ID */
private static final int DATA_ID_COLUMN = 0;
/** 数据列索引:内容 */
private static final int DATA_CONTENT_COLUMN = 1;
/** 数据列索引MIME 类型 */
private static final int DATA_MIME_TYPE_COLUMN = 2;
/** 数据列索引:模式 */
private static final int DATA_MODE_COLUMN = 3;
/** 便签列索引:父文件夹 ID */
private static final int NOTE_PARENT_ID_COLUMN = 0;
/** 便签列索引:提醒日期 */
private static final int NOTE_ALERTED_DATE_COLUMN = 1;
/** 便签列索引:背景颜色 ID */
private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
/** 便签列索引:小组件 ID */
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;
/** 便签列索引:是否置顶 */
private static final int NOTE_PINNED_COLUMN = 6;
/** 便签列索引:是否加密 */
private static final int NOTE_ENCRYPTED_COLUMN = 7;
/** 便签列索引:密码哈希值 */
private static final int NOTE_PASSWORD_HASH_COLUMN = 8;
/**
* 创建新便签的构造方法
* @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; // 初始状态为未删除
mMode = 0; // 初始模式为普通模式
mWidgetType = Notes.TYPE_WIDGET_INVALIDE; // 初始小组件类型为无效
mPinned = false; // 初始状态为未置顶
mEncrypted = false; // 初始状态为未加密
mPasswordHash = ""; // 初始密码哈希值为空
mTitle = ""; // 初始标题为空
}
/**
* 加载现有便签的构造方法
* @param context 上下文对象
* @param noteId 便签 ID
* @param folderId 文件夹 ID
*/
private WorkingNote(Context context, long noteId, long folderId) {
mContext = context; // 初始化上下文对象
mNoteId = noteId; // 设置便签 ID
mFolderId = folderId; // 设置文件夹 ID
mIsDeleted = false; // 初始状态为未删除
mNote = new Note(); // 创建新的 Note 对象
boolean loaded = loadNote(); // 加载便签数据
if (!loaded) {
Log.e(TAG, "Failed to load note with id:" + noteId); // 加载失败时记录错误日志
}
}
/**
* 加载便签基本信息
* 从数据库中查询便签的基本属性,如文件夹 ID、提醒日期、背景颜色等
* @return 是否加载成功
*/
private boolean loadNote() {
// 查询便签基本信息
Cursor cursor = mContext.getContentResolver().query(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null,
null, null);
boolean success = false; // 初始化加载成功标志
if (cursor != null) {
if (cursor.moveToFirst()) {
// 读取便签基本属性
mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN);
mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN);
mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);
mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);
mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);
mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
mPinned = (cursor.getInt(NOTE_PINNED_COLUMN) > 0) ? true : false;
mEncrypted = (cursor.getInt(NOTE_ENCRYPTED_COLUMN) > 0) ? true : false;
mPasswordHash = cursor.getString(NOTE_PASSWORD_HASH_COLUMN);
success = true; // 加载成功
}
cursor.close(); // 关闭游标
} else {
Log.e(TAG, "No note with id:" + mNoteId); // 记录错误日志
}
if (success) {
return loadNoteData(); // 加载成功后加载便签详细数据
}
return false; // 加载失败
}
/**
* 加载便签详细数据
* 从数据库中查询便签的内容、标题、模式等详细信息
* @return 是否加载成功
*/
private boolean loadNoteData() {
// 查询便签详细数据
Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,
DataColumns.NOTE_ID + "=?", new String[] {
String.valueOf(mNoteId)
}, null);
boolean success = false; // 初始化加载成功标志
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
if (DataConstants.NOTE.equals(type)) {
// 处理普通便签数据
mContent = cursor.getString(DATA_CONTENT_COLUMN);
mTitle = cursor.getString(5); // DATA3 列存储标题(索引 5
mMode = cursor.getInt(DATA_MODE_COLUMN);
mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));
success = true; // 加载成功
} else if (DataConstants.CALL_NOTE.equals(type)) {
// 处理通话便签数据
mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));
success = true; // 加载成功
} else {
Log.d(TAG, "Wrong note type with type:" + type); // 记录错误类型日志
}
} while (cursor.moveToNext());
}
cursor.close(); // 关闭游标
} else {
Log.e(TAG, "No data with id:" + mNoteId); // 记录错误日志
}
return success; // 返回加载结果
}
/**
* 创建空便签
* @param context 上下文对象
* @param folderId 文件夹 ID
* @param widgetId 小组件 ID
* @param widgetType 小组件类型
* @param defaultBgColorId 默认背景颜色 ID
* @return 创建的空便签对象
*/
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
int widgetType, int defaultBgColorId) {
WorkingNote note = new WorkingNote(context, folderId);
note.setBgColorId(defaultBgColorId); // 设置默认背景颜色
note.setWidgetId(widgetId); // 设置小组件 ID
note.setWidgetType(widgetType); // 设置小组件类型
return note;
}
/**
* 加载指定 ID 的便签
* @param context 上下文对象
* @param id 便签 ID
* @return 加载的便签对象
*/
public static WorkingNote load(Context context, long id) {
return new WorkingNote(context, id, 0);
}
/**
* 保存便签
* @return 是否保存成功
*/
public synchronized boolean saveNote() {
if (isWorthSaving()) { // 检查是否值得保存
if (!existInDatabase()) { // 检查是否已存在于数据库
// 创建新便签
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
Log.e(TAG, "Create new note fail with id:" + mNoteId);
return false;
}
}
mNote.syncNote(mContext, mNoteId); // 同步便签数据到数据库
/**
* 如果便签关联了小组件,更新小组件内容
*/
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE
&& mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onWidgetChanged(); // 通知小组件变更
}
return true;
} else {
return false;
}
}
/**
* 检查便签是否已存在于数据库
* @return 是否已存在于数据库
*/
public boolean existInDatabase() {
return mNoteId > 0;
}
/**
* 检查便签是否值得保存
* @return 是否值得保存
*/
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) {
Log.d(TAG, "setAlertDate: date=" + date + ", set=" + set);
mAlertDate = date; // 设置提醒日期
mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate)); // 同步到 Note 对象
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(); // 通知监听器
}
}
/**
* 检查便签是否已删除
* @return 是否已删除
*/
public boolean isDeleted() {
return mIsDeleted;
}
/**
* 设置背景颜色 ID
* @param id 背景颜色 ID
*/
public void setBgColorId(int id) {
if (id != mBgColorId) { // 检查颜色是否变更
mBgColorId = id; // 设置背景颜色 ID
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onBackgroundColorChanged(); // 通知监听器
}
mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id)); // 同步到 Note 对象
}
}
/**
* 设置便签模式
* @param mode 模式(普通模式或 checklist 模式)
*/
public void setCheckListMode(int mode) {
if (mMode != mode) { // 检查模式是否变更
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode); // 通知监听器
}
mMode = mode; // 设置模式
mNote.setTextData(TextNote.MODE, String.valueOf(mMode)); // 同步到 Note 对象
}
}
/**
* 设置小组件类型
* @param type 小组件类型
*/
public void setWidgetType(int type) {
if (type != mWidgetType) { // 检查类型是否变更
mWidgetType = type; // 设置小组件类型
mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType)); // 同步到 Note 对象
}
}
/**
* 设置小组件 ID
* @param id 小组件 ID
*/
public void setWidgetId(int id) {
if (id != mWidgetId) { // 检查 ID 是否变更
mWidgetId = id; // 设置小组件 ID
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId)); // 同步到 Note 对象
}
}
/**
* 设置便签内容
* @param text 便签内容
*/
public void setWorkingText(String text) {
if (!TextUtils.equals(mContent, text)) { // 检查内容是否变更
mContent = text; // 设置便签内容
mNote.setTextData(DataColumns.CONTENT, mContent); // 同步到 Note 对象
mModifiedDate = System.currentTimeMillis(); // 更新修改日期
}
}
/**
* 设置便签标题
* @param title 便签标题
*/
public void setTitle(String title) {
if (!TextUtils.equals(mTitle, title)) { // 检查标题是否变更
mTitle = title; // 设置便签标题
mNote.setTextData(DataColumns.DATA3, mTitle); // 同步到 Note 对象
mModifiedDate = System.currentTimeMillis(); // 更新修改日期
}
}
/**
* 获取便签标题
* @return 便签标题
*/
public String getTitle() {
return mTitle;
}
/**
* 将便签转换为通话便签
* @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)); // 设置父文件夹为通话记录文件夹
}
/**
* 检查便签是否有提醒
* @return 是否有提醒
*/
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
* @return 背景颜色资源 ID
*/
public int getBgColorResId() {
return NoteBgResources.getNoteBgResource(mBgColorId);
}
/**
* 获取背景颜色 ID
* @return 背景颜色 ID
*/
public int getBgColorId() {
return mBgColorId;
}
/**
* 获取标题背景资源 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
* @return 文件夹 ID
*/
public long getFolderId() {
return mFolderId;
}
/**
* 获取小组件 ID
* @return 小组件 ID
*/
public int getWidgetId() {
return mWidgetId;
}
/**
* 获取小组件类型
* @return 小组件类型
*/
public int getWidgetType() {
return mWidgetType;
}
/**
* 检查便签是否置顶
* @return 是否置顶
*/
public boolean isPinned() {
return mPinned;
}
/**
* 设置便签是否置顶
* @param pinned 是否置顶
*/
public void setPinned(boolean pinned) {
if (mPinned != pinned) { // 检查置顶状态是否变更
mPinned = pinned; // 设置置顶状态
mNote.setNoteValue(NoteColumns.PINNED, String.valueOf(mPinned ? 1 : 0)); // 同步到 Note 对象
}
}
/**
* 检查便签是否加密
* @return 是否加密
*/
public boolean isEncrypted() {
return mEncrypted;
}
/**
* 设置便签是否加密
* @param encrypted 是否加密
*/
public void setEncrypted(boolean encrypted) {
if (mEncrypted != encrypted) { // 检查加密状态是否变更
mEncrypted = encrypted; // 设置加密状态
mNote.setNoteValue(NoteColumns.ENCRYPTED, String.valueOf(mEncrypted ? 1 : 0)); // 同步到 Note 对象
}
}
/**
* 设置密码哈希值
* @param passwordHash 密码哈希值
*/
public void setPasswordHash(String passwordHash) {
mPasswordHash = passwordHash; // 设置密码哈希值
mNote.setNoteValue(NoteColumns.PASSWORD_HASH, mPasswordHash); // 同步到 Note 对象
}
/**
* 验证密码
* @param password 待验证的密码
* @return 密码是否正确
*/
public boolean verifyPassword(String password) {
return net.micode.notes.tool.EncryptionUtils.generatePasswordHash(password).equals(mPasswordHash);
}
/**
* 便签设置变更监听器接口
* 用于监听便签设置的变更,如背景颜色、提醒、小组件等
*/
public interface NoteSettingChangedListener {
/**
* 当便签背景颜色变更时调用
*/
void onBackgroundColorChanged();
/**
* 当用户设置提醒时调用
* @param date 提醒日期
* @param set 是否设置提醒
*/
void onClockAlertChanged(long date, boolean set);
/**
* 当用户从小组件创建便签时调用
*/
void onWidgetChanged();
/**
* 当切换 checklist 模式和普通模式时调用
* @param oldMode 变更前的模式
* @param newMode 变更后的模式
*/
void onCheckListModeChanged(int oldMode, int newMode);
}
}