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.

587 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.
*/
/**
* 文件: WorkingNote.java
* 描述: 便签工作模型类用于在UI层和数据层之间进行交互
* 作用: 提供便签编辑、保存、加载等操作的高级接口,管理便签的各种属性和状态
*/
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;
/**
* 便签工作模型类
*
* 该类是应用的核心模型类,负责便签数据的加载、编辑和保存操作
* 提供了便签的所有属性访问和修改方法,如内容、背景颜色、提醒时间等
* 作为UI层和数据层之间的桥梁处理便签的各种状态变化
*/
public class WorkingNote {
/** 底层便签数据模型 */
private Note mNote;
/** 便签ID */
private long mNoteId;
/** 便签内容 */
private String mContent;
/** 便签模式(普通模式或清单模式) */
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,
DataColumns.DATA1,
DataColumns.DATA2,
DataColumns.DATA3,
DataColumns.DATA4,
};
/**
* 便签查询投影:定义查询便签时需要获取的列
*/
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
};
/** 数据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;
/**
* 创建新便签的构造函数
*
* @param context 上下文环境
* @param folderId 所属文件夹ID
*/
private WorkingNote(Context context, long folderId) {
mContext = context;
mAlertDate = 0;
mModifiedDate = System.currentTimeMillis();
mFolderId = folderId;
mNote = new Note();
mNoteId = 0;
mIsDeleted = false;
mMode = 0;
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
}
/**
* 加载已有便签的构造函数
*
* @param context 上下文环境
* @param noteId 便签ID
* @param folderId 所属文件夹ID
*/
private WorkingNote(Context context, long noteId, long folderId) {
mContext = context;
mNoteId = noteId;
mFolderId = folderId;
mIsDeleted = false;
mNote = new Note();
loadNote();
}
/**
* 从数据库加载便签基本信息
*/
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);
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);
}
cursor.close();
} else {
Log.e(TAG, "No note with id:" + mNoteId);
throw new IllegalArgumentException("Unable to find note with id " + mNoteId);
}
// 加载便签内容数据
loadNoteData();
}
/**
* 从数据库加载便签内容数据
*/
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 {
// 根据数据类型处理不同的便签内容
String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
if (DataConstants.NOTE.equals(type)) {
// 处理文本便签数据
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));
} 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);
}
}
/**
* 创建空便签
*
* @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);
note.setWidgetId(widgetId);
note.setWidgetType(widgetType);
return note;
}
/**
* 加载已有便签
*
* @param context 上下文环境
* @param id 便签ID
* @return 加载的WorkingNote对象
*/
public static WorkingNote load(Context context, long id) {
return new WorkingNote(context, id, 0);
}
/**
* 保存便签到数据库
*
* @return 保存成功返回true失败返回false
*/
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);
/**
* 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() {
return mNoteId > 0;
}
/**
* 检查便签是否值得保存
* 判断条件:
* 1. 便签未被删除
* 2. 如果是新便签,内容不为空
* 3. 如果是已有便签,有本地修改
*
* @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 true表示已删除false表示未删除
*/
public void markDeleted(boolean mark) {
mIsDeleted = mark;
// 如果便签有关联的小部件,通知小部件变更
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onWidgetChanged();
}
}
/**
* 设置背景颜色ID
*
* @param id 背景颜色ID
*/
public void setBgColorId(int id) {
if (id != mBgColorId) {
mBgColorId = id;
// 通知背景颜色变更
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onBackgroundColorChanged();
}
mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(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
*
* @param id 小部件ID
*/
public void setWidgetId(int id) {
if (id != mWidgetId) {
mWidgetId = id;
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
}
}
/**
* 设置便签内容
*
* @param text 便签内容文本
*/
public void setWorkingText(String text) {
if (!TextUtils.equals(mContent, text)) {
mContent = text;
mNote.setTextData(DataColumns.CONTENT, mContent);
}
}
/**
* 将普通便签转换为通话记录便签
*
* @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 有提醒返回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
*
* @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;
}
/**
* 便签设置变更监听器接口
* 用于通知便签设置的各种变更事件
*/
public interface NoteSettingChangedListener {
/**
* Called when the background color of current note has just changed
*/
void onBackgroundColorChanged();
/**
* Called when user set clock
*/
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
*/
void onCheckListModeChanged(int oldMode, int newMode);
}
}