diff --git a/许超雨/model/Note.java b/许超雨/model/Note.java new file mode 100644 index 0000000..a0e070d --- /dev/null +++ b/许超雨/model/Note.java @@ -0,0 +1,268 @@ +/* + * µ¥¸ö±ãÇ©Ïî +* 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.content.ContentProviderOperation;//ÅúÁ¿µÄ¸üС¢²åÈ롢ɾ³ýÊý¾Ý +import android.content.ContentProviderResult;//²Ù×÷½á¹û +import android.content.ContentUris;//Ìí¼Ó»òÕßÐÞ¸ÄuriºóÃæµÄID +import android.content.ContentValues;//´æ´¢»ù±¾Êý¾ÝÀàÐ͵ÄÊý¾Ý +import android.content.Context;// »ñÈ¡µ÷ÓÃÄÚÈÝ +import android.content.OperationApplicationException;//²Ù×÷Êý¾ÝÈÝ´í +import android.net.Uri;//UriÏà¹Ø²Ù×÷£¬±êʶΨһµÄ×ÊÔ´ +import android.os.RemoteException;//Òì³£´¦Àí +import android.util.Log;//Êä³öÈÕÖ¾£¬±ÈÈç˵³ö´í¡¢¾¯¸æµÈ + +import net.micode.notes.data.Notes;//СÃ×±ãǩһЩÊôÐԵIJÙ×÷ +import net.micode.notes.data.Notes.CallNote;//µ÷ÓòÙ×÷ +import net.micode.notes.data.Notes.DataColumns;//Êý¾ÝÀ¸ +import net.micode.notes.data.Notes.NoteColumns;//±Ê¼ÇÀ¸ +import net.micode.notes.data.Notes.TextNote;//²Ù×÷Çø + +import java.util.ArrayList;//µ¼ÈëJava,util,ArrayList + + +public class Note {//¶¨ÒånoteÀ࣬´¦Àíµ¥¸ö±ãÇ© + private ContentValues mNoteDiffValues;//ÉùÃ÷Ò»¸öContentValues˽ÓбäÁ¿ContentValues£¬ÓÃÀ´´æ´¢noteÓëÉÏ´ÎÐ޸ĺóµÄ¸Ä¶¯ + private NoteData mNoteData;//ÉùÃ÷Ò»¸ö˽ÓбäÁ¿NoteData£¬ÓÃÀ´¼Ç¼µ¥¸ö±ãÇ©µÄ»ù±¾ÐÅÏ¢ + private static final String TAG = "Note";//ÉèÖÃÈí¼þ±êÇ© + /** + * Create a new note id for adding a new note to databases + */ + public static synchronized long getNewNoteId(Context context, long folderId) { + //Create a new note in the database + /* + * ×÷ÓãºÎªÐ±ãÇ©ÔÚÊý¾Ý¿âÀï±ß´´½¨Ò»¸öеÄID + * ʵÏÖ£º´´½¨Ò»¸öÄÚÈݼ¯ºÏ£¬´æÈë´´½¨±ãÇ©µÄʱ¼ä£¬×îºóÐ޸ĵÄʱ¼ä£¬ÔÙ¸ù¾Ýµ±Ç°±ãÇ©Ëù´¦µÄÉÏÏÂÎĺÍÎļþ¼ÐµÄID£¬´ÓÄÚÈݽâÎöÆ÷Öеõ½µÄ·¾¶uriÀïÃæ + * »ñȡеıãÇ©µÄID¡£×îºóÅжÏIDÊÇ·ñºÏ·¨£¬È»ºó·µ»Ø + * ²ÎÊý£º@context£º±ãÇ©Ëù´¦µÄÉÏÏÂÎÄ + * @folderId£ºËù´¦µÄ±ãÇ©Îļþ¼ÐID + * @return£ºÐ´´½¨±ãÇ©µÄID + */ + ContentValues values = new ContentValues(); + long createdTime = System.currentTimeMillis(); + values.put(NoteColumns.CREATED_DATE, createdTime); + values.put(NoteColumns.MODIFIED_DATE, createdTime); + values.put(NoteColumns.TYPE, Notes.TYPE_NOTE); + values.put(NoteColumns.LOCAL_MODIFIED, 1); + values.put(NoteColumns.PARENT_ID, folderId); + Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values); + + long noteId = 0; + try { + noteId = Long.valueOf(uri.getPathSegments().get(1)); + } catch (NumberFormatException e) { + Log.e(TAG, "Get note id error :" + e.toString()); + noteId = 0; + } + if (noteId == -1) { + throw new IllegalStateException("Wrong note id:" + noteId); + } + return noteId; + } + + public Note() {//¶¨ÒåÁ½¸ö±äÁ¿ÓÃÀ´´æ´¢±ãÇ©µÄÊý¾Ý£¬Ò»¸öÊÇ´æ´¢±ãÇ©ÊôÐÔ¡¢Ò»¸öÊÇ´æ´¢±ãÇ©ÄÚÈÝ + mNoteDiffValues = new ContentValues(); + mNoteData = new NoteData(); + } + + public void setNoteValue(String key, String value) { + /* + * ×÷ÓãºÉèÖñãÇ©µÄÊôÐÔ + * ʵÏÖ£ºÍ¨¹ý´«Èëkey£¬Ö¸¶¨Ð޸ıãÇ©µÄÊôÐÔ£»´«Èëvalue£¬Ö¸¶¨Ð޸ĵÄÖµ£¬Í¨¹ýÊôÐÔ¹ÜÀíÆ÷mNoteDiffValuesдÈë¡£×îºó£¬¸Ä±ä×îºóÐÞ¸Äʱ¼ä + * ²ÎÊý£º@key£ºÒªÐ޸ĵÄÊôÐÔ + * @value£ºÒªÐ޸ĵÄÖµ + */ + mNoteDiffValues.put(key, value); + mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1); + mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); + } + + public void setTextData(String key, String value) {//ÉèÖÃÊý¾Ý¿â±í¸ñµÄ±êÇ©Îı¾ÄÚÈݵÄÊý¾Ý + mNoteData.setTextData(key, value); + } + + public void setTextDataId(long id) {//ÉèÖÃÎı¾Êý¾ÝµÄID + mNoteData.setTextDataId(id); + } + + public long getTextDataId() {//»ñÈ¡Îı¾Êý¾ÝµÄID + return mNoteData.mTextDataId; + } + + public void setCallDataId(long id) {//ÉèÖõ绰ºÅÂëÊý¾ÝµÄID + mNoteData.setCallDataId(id); + } + + public void setCallData(String key, String value) {//ÉèÖõ绰ºÅÂëµÄÊý¾Ý + mNoteData.setCallData(key, value); + } + + public boolean isLocalModified() {//ÅжϱãÇ©ÊÇ·ñ½øÐÐÁ˱¾µØÐÞ¸Ä + return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified(); + } + + public boolean syncNote(Context context, long noteId) {//Åж϶ÔÐ޸ĹýµÄ±ãÇ©ÊÇ·ñ½øÐÐͬ²½ + if (noteId <= 0) { + throw new IllegalArgumentException("Wrong note id:" + noteId); + } + + if (!isLocalModified()) { + return true; + } + + /** + * In theory, once data changed, the note should be updated on {@link NoteColumns#LOCAL_MODIFIED} and + * {@link NoteColumns#MODIFIED_DATE}. For data safety, though update note fails, we also update the + * note data info + */ + if (context.getContentResolver().update( + ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), mNoteDiffValues, null, + null) == 0) { + Log.e(TAG, "Update note error, should not happen"); + // Do not return, fall through + } + mNoteDiffValues.clear(); + + if (mNoteData.isLocalModified() + && (mNoteData.pushIntoContentResolver(context, noteId) == null)) { + return false; + } + + return true; + } + + private class NoteData {//¶¨ÒåÒ»¸ö»ù±¾µÄ±ãÇ©ÄÚÈݵÄÊý¾ÝÀ࣬Ö÷Òª°üº¬Îı¾Êý¾ÝºÍµç»°ºÅÂëÊý¾Ý + private long mTextDataId;//Îı¾Êý¾Ýid + + private ContentValues mTextDataValues;//Îı¾Êý¾ÝÄÚÈÝ + + private long mCallDataId;//µç»°ºÅÂëÊý¾ÝID + + private ContentValues mCallDataValues;//µç»°ºÅÂëÊý¾ÝÄÚÈÝ + + private static final String TAG = "NoteData";//ĬÈϹ¹Ô캯Êý + + public NoteData() {//NoteDataµÄ¹¹Ô캯Êý£¬³õʼ»¯Ëĸö±äÁ¿ + mTextDataValues = new ContentValues(); + mCallDataValues = new ContentValues(); + mTextDataId = 0; + mCallDataId = 0; + } + + boolean isLocalModified() {//ÅжÏÊÇ·ñ±¾µØÐÞ¸Ä + return mTextDataValues.size() > 0 || mCallDataValues.size() > 0; + } + + void setTextDataId(long id) {//ÉèÖÃÎı¾Êý¾ÝµÄID + if(id <= 0) { + throw new IllegalArgumentException("Text data id should larger than 0"); + } + mTextDataId = id; + } + + void setCallDataId(long id) {//ÉèÖõ绰ºÅÂë¶ÔÓ¦µÄid + if (id <= 0) { + throw new IllegalArgumentException("Call data id should larger than 0"); + } + mCallDataId = id; + } + + void setCallData(String key, String value) {//ÉèÖõ绰ºÅÂëÊý¾ÝÄÚÈÝ£¬²¢ÇÒ±£´æÐÞ¸Äʱ¼ä + mCallDataValues.put(key, value); + mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1); + mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); + } + + void setTextData(String key, String value) {//ÉèÖÃÎı¾Êý¾Ý + mTextDataValues.put(key, value); + mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1); + mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); + } + + Uri pushIntoContentResolver(Context context, long noteId) {//ʹÓÃuri½«Êý¾ÝÌí¼Óµ½Êý¾Ý¿â + /** + * Check for safety + */ + if (noteId <= 0) {//ÅжÏÊý¾ÝÊÇ·ñºÏ·¨ + throw new IllegalArgumentException("Wrong note id:" + noteId); + } + + ArrayList operationList = new ArrayList(); + ContentProviderOperation.Builder builder = null; + + if(mTextDataValues.size() > 0) {//°ÑÎı¾Êý¾Ý´æÈëDataColumns + mTextDataValues.put(DataColumns.NOTE_ID, noteId); + if (mTextDataId == 0) {//Îı¾Êý¾ÝIDΪÁ㣬Òâζ×ÅÕâ¸öidÊÇн¨Ä¬ÈϵÄid + mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE); + Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, + mTextDataValues); + try { + setTextDataId(Long.valueOf(uri.getPathSegments().get(1))); + } catch (NumberFormatException e) { + Log.e(TAG, "Insert new text data fail with noteId" + noteId); + mTextDataValues.clear(); + return null; + } + } else { + builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mTextDataId)); + builder.withValues(mTextDataValues); + operationList.add(builder.build()); + } + mTextDataValues.clear(); + } + + if(mCallDataValues.size() > 0) {//µç»°ºÅÂëͬ²½ + mCallDataValues.put(DataColumns.NOTE_ID, noteId); + if (mCallDataId == 0) {//½«µç»°ºÅÂëµÄidÉ趨ΪuriÌṩµÄid + mCallDataValues.put(DataColumns.MIME_TYPE, CallNote.CONTENT_ITEM_TYPE); + Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, + mCallDataValues); + try { + setCallDataId(Long.valueOf(uri.getPathSegments().get(1))); + } catch (NumberFormatException e) { + Log.e(TAG, "Insert new call data fail with noteId" + noteId); + mCallDataValues.clear(); + return null; + } + } else {//µ±µç»°ºÅÂ벻Ϊн¨Ê±£¬¸üе绰ºÅÂëID + builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mCallDataId)); + builder.withValues(mCallDataValues); + operationList.add(builder.build()); + } + mCallDataValues.clear(); + } + + if (operationList.size() > 0) {//´æ´¢¹ý³ÌÖÐÈç¹ûÓöµ½Òì³££¬Í¨¹ýÈçϽøÐд¦Àí + try {//Å׳öÔ¶³ÌÒì³££¬²¢Ð´»ØÈÕÖ¾ + ContentProviderResult[] results = context.getContentResolver().applyBatch( + Notes.AUTHORITY, operationList); + return (results == null || results.length == 0 || results[0] == null) ? null + : ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId); + } catch (RemoteException e) {//²¶×½²Ù×÷Òì³£²¢Ð´»ØÈÕÖ¾ + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + return null; + } catch (OperationApplicationException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));//Òì³£ÈÕÖ¾ + return null; + } + } + return null; + } + } +} diff --git a/许超雨/model/WorkingNote.java b/许超雨/model/WorkingNote.java new file mode 100644 index 0000000..f78e8b0 --- /dev/null +++ b/许超雨/model/WorkingNote.java @@ -0,0 +1,370 @@ +/*µ±Ç°»î¶¯±ãÇ©Ïî + * 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;//ÔÚ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; + + +public class WorkingNote {/*ÉùÃ÷WorkingNoteÀà,´´½¨Ð¡Ã×±ãÇ©µÄÖ÷ÒªÀ࣬ + °üÀ¨´´½¨¿Õ±ãÇ©£¬±£´æ±ãÇ©£¬¼ÓÔØÐ¡Ã×±ãÇ©ÄÚÈÝ£¬ºÍÉèÖÃСÃ×±ãÇ©µÄһЩС²¿¼þÖ®ÀàµÄ²Ù×÷*/ + // Note for the working 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; + + private int mBgColorId; + + private int mWidgetId; + + private int mWidgetType; + + 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[] {/*ÉùÃ÷NOTE_PROJECTION×Ö·û´®Êý×飬 + ÓÃÓÚ´æ´¢Êý¾ÝÐÅÏ¢¡£*/ + DataColumns.ID, + DataColumns.CONTENT, + DataColumns.MIME_TYPE, + DataColumns.DATA1, + DataColumns.DATA2, + DataColumns.DATA3, + DataColumns.DATA4, + }; + + public static final String[] NOTE_PROJECTION = new String[] {//±£´æ±ãÇ©ÊôÐÔÐÅÏ¢µÄstringÊý×é + NoteColumns.PARENT_ID, + NoteColumns.ALERTED_DATE, + NoteColumns.BG_COLOR_ID, + NoteColumns.WIDGET_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 + private WorkingNote(Context context, long folderId) {//³õʼ»¯WorkingNoteÀàµÄÄÚ²¿Êý¾Ý±äÁ¿ + mContext = context; + mAlertDate = 0; + mModifiedDate = System.currentTimeMillis();//»ñȡϵͳµ±Ç°Ê±¼äµÄ·½·¨£¬·µ»Øµ±Ç°Ê±¼ä + mFolderId = folderId; + mNote = new Note();//¼ÓÔØÒ»¸öÒÑ´æÔڵıãÇ© + mNoteId = 0; + mIsDeleted = false; + mMode = 0; + mWidgetType = Notes.TYPE_WIDGET_INVALIDE;//ĬÈÏÊDz»¿É¼û + } + + // Existing note construct + 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); + } + } + + 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; + } + + public static WorkingNote load(Context context, long id) {//¼ÓÔØÒѾ­´´½¨µÄ±ãÇ© + return new WorkingNote(context, id, 0); + } + + public synchronized boolean saveNote() {//±£´æ±ãÇ©£¬³É¹¦±£´æ·µ»Øtrue£¬·ñÔò·µ»Øfalse + 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; + } + } + + public boolean existInDatabase() {//²é¿´¸ÃnoteÊÇ·ñÒѾ­´æ·Åµ½Êý¾Ý¿âÖÐ + return mNoteId > 0; + } + + private boolean isWorthSaving() {//ÅжÏÊÇ·ñÐèÒª±£´æ + if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent)) + || (existInDatabase() && !mNote.isLocalModified())) { + return false; + } else { + return true; + } + } + + public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {//ÉèÖÃ״̬¸Ä±äµÄ¼àÌýÆ÷ + mNoteSettingStatusListener = l; + } + + 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); + } + } + + public void markDeleted(boolean mark) {//ÉèÖÃɾ³ý±êÖ¾ + mIsDeleted = mark; + if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID + && mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) { + mNoteSettingStatusListener.onWidgetChanged(); + } + } + + public void setBgColorId(int id) {//É趨±³¾°ÑÕÉ« + if (id != mBgColorId) { + mBgColorId = id; + if (mNoteSettingStatusListener != null) { + mNoteSettingStatusListener.onBackgroundColorChanged(); + } + mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id)); + } + } + + public void setCheckListMode(int mode) {//ÉèÖüì²éÁбíģʽ + if (mMode != mode) { + if (mNoteSettingStatusListener != null) { + mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode); + } + mMode = mode; + mNote.setTextData(TextNote.MODE, String.valueOf(mMode)); + } + } + + public void setWidgetType(int type) {//ÉèÖô°¿ÚÀàÐÍ + if (type != mWidgetType) { + mWidgetType = type; + mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType)); + } + } + + public void setWidgetId(int id) {//ÉèÖô°¿Ú±àºÅ + if (id != mWidgetId) { + mWidgetId = id; + mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId)); + } + } + + public void setWorkingText(String text) {//дÈëÎı¾ÄÚÈÝ + if (!TextUtils.equals(mContent, text)) { + mContent = text; + mNote.setTextData(DataColumns.CONTENT, mContent); + } + } + + 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)); + } + + public boolean hasClockAlert() {//¼ì²âÊÇ·ñÓÐʱÖÓÌáÐÑ£¬mAlertDate > 0·µ»ØÕ棬·ñÔò·µ»Ø¼Ù + return (mAlertDate > 0 ? true : false); + } + + public String getContent() {//»ñÈ¡±ãÇ©ÄÚÈÝ + return mContent; + } + + public long getAlertDate() {//»ñÈ¡ÌáÐÑʱ¼ä + return mAlertDate; + } + + public long getModifiedDate() {//»ñÈ¡ÐÞ¸Äʱ¼ä + return mModifiedDate; + } + + public int getBgColorResId() {//»ñÈ¡±³¾°ÑÕÉ«À´Ô´id + return NoteBgResources.getNoteBgResource(mBgColorId); + } + + public int getBgColorId() {//»ñÈ¡±³¾°ÑÕÉ«id + return mBgColorId; + } + + public int getTitleBgResId() {//»ñÈ¡±êÌâ±³¾°ÑÕÉ«×ÊÔ´µÄid + return NoteBgResources.getNoteTitleBgResource(mBgColorId); + } + + public int getCheckListMode() {//»ñÈ¡Ç嵥ģʽ + return mMode; + } + + public long getNoteId() {//»ñÈ¡±ãÇ©id + return mNoteId; + } + + public long getFolderId() {//»ñÈ¡Îļþ¼Ðid + return mFolderId; + } + + public int getWidgetId() {//»ñÈ¡´°¿Úid + return mWidgetId; + } + + 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);//±ãÇ©¼ì²éÁбíģʽ¸Ä±ä + } +} diff --git a/许超雨/ui/NotesListAdapter.java b/许超雨/ui/NotesListAdapter.java new file mode 100644 index 0000000..fea3146 --- /dev/null +++ b/许超雨/ui/NotesListAdapter.java @@ -0,0 +1,184 @@ +/* + * 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;//ÒýÈëtools°ü + +import android.content.Context;//µ¼Èë¸÷ÖÖÀà +import android.database.Cursor; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CursorAdapter; + +import net.micode.notes.data.Notes; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + + +public class NotesListAdapter extends CursorAdapter {//¼Ì³Ð×ÔCursorAdapter£¬ËüΪcursorºÍListViewÌṩÁËÁ¬½ÓµÄÇÅÁº¡£Òò´Ë£¬¸ÃÀàΪcursorºÍ±ãÇ©±à¼­ÌṩÁ˹µÍ¨ÇþµÀ + private static final String TAG = "NotesListAdapter"; + private Context mContext; + private HashMap mSelectedIndex; + private int mNotesCount; + private boolean mChoiceMode; + + public static class AppWidgetAttribute {//±íʾ×ÀÃæwidgetµÄÊôÐÔ£¬°üÀ¨±àºÅºÍÀàÐÍ + public int widgetId; + public int widgetType; + }; + + public NotesListAdapter(Context context) {//³õʼ»¯±ãÇ©Á´½Ó + super(context, null); + mSelectedIndex = new HashMap(); + mContext = context; + mNotesCount = 0; + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) {//ÀûÓÃNotesListLtemÀà´´½¨Ð²¼¾Ö + return new NotesListItem(context); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) {//½«¹â±êÖ¸ÏòµÄÊý¾ÝÓë´´½¨µÄÊÓͼÀ¦°óÆðÀ´ + if (view instanceof NotesListItem) { + NoteItemData itemData = new NoteItemData(context, cursor); + ((NotesListItem) view).bind(context, itemData, mChoiceMode, + isSelectedItem(cursor.getPosition())); + } + } + + public void setCheckedItem(final int position, final boolean checked) {//ÉèÖù´Ñ¡¿ò + mSelectedIndex.put(position, checked); + notifyDataSetChanged(); + } + + public boolean isInChoiceMode() {//ÅжÏÊÇ·ñ±»¹´Ñ¡ + return mChoiceMode; + } + + public void setChoiceMode(boolean mode) {//ÖØÖù´Ñ¡¿ò + mSelectedIndex.clear(); + mChoiceMode = mode; + } + + public void selectAll(boolean checked) {//ÉèÖÃÈ«²¿¹´Ñ¡ + Cursor cursor = getCursor(); + for (int i = 0; i < getCount(); i++) { + if (cursor.moveToPosition(i)) { + if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) { + setCheckedItem(i, checked); + } + } + } + } + + public HashSet getSelectedItemIds() {// »ñÈ¡ÒѾ­±»¹´Ñ¡µÄÏîÄ¿µÄidºÅ¼ÓÈ뵽ɢÁбíitemSetÖÐ + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Long id = getItemId(position); + if (id == Notes.ID_ROOT_FOLDER) { + Log.d(TAG, "Wrong item id, should not happen"); + } else { + itemSet.add(id); + } + } + } + + return itemSet; + } + + public HashSet getSelectedWidget() {//»ñÈ¡×ÀÃæ×é¼þÑ¡Ïî±í + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) {//±éÀú±»Ñ¡ÖеÄÁбí + if (mSelectedIndex.get(position) == true) { + Cursor c = (Cursor) getItem(position); + if (c != null) { + AppWidgetAttribute widget = new AppWidgetAttribute(); + NoteItemData item = new NoteItemData(mContext, c); + widget.widgetId = item.getWidgetId(); + widget.widgetType = item.getWidgetType(); + itemSet.add(widget); + /** + * Don't close cursor here, only the adapter could close it + */ + } else { + Log.e(TAG, "Invalid cursor");//ÉèÖñêÇ©£¬·Ç·¨µÄcursor + return null; + } + } + } + return itemSet; + } + + public int getSelectedCount() {//»ñȡѡÏî¸öÊý + Collection values = mSelectedIndex.values();//»ñȡѡÏîϱêµÄÖµ + if (null == values) { + return 0; + } + Iterator iter = values.iterator();//³õʼ»¯µþ¼ÓÆ÷ + int count = 0; + while (iter.hasNext()) { + if (true == iter.next()) { + count++; + } + } + return count; + } + + public boolean isAllSelected() {//ÅжÏÊÇ·ñȫѡ + int checkedCount = getSelectedCount(); + return (checkedCount != 0 && checkedCount == mNotesCount); + } + + public boolean isSelectedItem(final int position) {//ÅжÏÊÇ·ñΪѡÏî±í + if (null == mSelectedIndex.get(position)) { + return false; + } + return mSelectedIndex.get(position); + } + + @Override + protected void onContentChanged() {//ÔÚactivity·¢Éú±ä»¯Ê±£¬ÖØÐ¼ÆËã±ãÇ©ÊýÁ¿ + super.onContentChanged(); + calcNotesCount(); + } + + @Override + public void changeCursor(Cursor cursor) {//¹â±ê±ä¶¯Ê±ÖØÐ¼ÆËã±ãÇ©ÊýÁ¿ + super.changeCursor(cursor); + calcNotesCount(); + } + + private void calcNotesCount() {//¼ÆË㵱ǰ½çÃæ±ãÇ©µÄÊýÁ¿ + mNotesCount = 0; + for (int i = 0; i < getCount(); i++) {//±éÀúËùÓÐÊý¾Ý + Cursor c = (Cursor) getItem(i); + if (c != null) {//ÅжÏÓï¾ä£¬Èç¹û¹â±ê²»ÊÇnull£¬ÄÇô±ãµÃµ½ÐÅÏ¢£¬±ãÇ©ÊýÄ¿¼Ó1 + if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) {//ÈôÑ¡ÏîµÄÊý¾ÝÀàÐÍΪ±ãÇ©ÀàÐÍ£¬ÄÇô¼ÆÊý+1 + mNotesCount++; + } + } else {//ÉèÖÃΪÎÞЧµÄ¹â±ê + Log.e(TAG, "Invalid cursor"); + return; + } + } + } +}