From 1db8c7053dbf037a307b3fb556bb4d233ed872e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=B1=B3=E4=BE=BF=E7=AD=BE?= <2107606387@qq.com> Date: Fri, 22 Nov 2024 09:08:24 +0800 Subject: [PATCH] test --- ...pg => 5521ad1a33aaae1d739e2693e4c0152.jpg} | Bin doc/912646d2f6d177b304c182a20c4e9d8.png | Bin 598255 -> 0 bytes ...便签开源代码的泛读报告111.docx | Bin 491392 -> 0 bytes src/Notesmaster/.idea/vcs.xml | 6 + src/Notesmaster/app/build.gradle.kts | 29 +- .../java/net/micode/notes/data/Contact.java | 73 ++ .../java/net/micode/notes/data/Notes.java | 279 +++++ .../notes/data/NotesDatabaseHelper.java | 362 +++++++ .../net/micode/notes/data/NotesProvider.java | 305 ++++++ .../net/micode/notes/gtask/data/MetaData.java | 82 ++ .../net/micode/notes/gtask/data/Node.java | 101 ++ .../net/micode/notes/gtask/data/SqlData.java | 189 ++++ .../net/micode/notes/gtask/data/SqlNote.java | 505 +++++++++ .../net/micode/notes/gtask/data/Task.java | 351 +++++++ .../net/micode/notes/gtask/data/TaskList.java | 343 +++++++ .../exception/ActionFailureException.java | 33 + .../exception/NetworkFailureException.java | 33 + .../notes/gtask/remote/GTaskASyncTask.java | 123 +++ .../notes/gtask/remote/GTaskClient.java | 585 +++++++++++ .../notes/gtask/remote/GTaskManager.java | 800 +++++++++++++++ .../notes/gtask/remote/GTaskSyncService.java | 128 +++ .../java/net/micode/notes/model/Note.java | 253 +++++ .../net/micode/notes/model/WorkingNote.java | 368 +++++++ .../net/micode/notes/tool/BackupUtils.java | 344 +++++++ .../java/net/micode/notes/tool/DataUtils.java | 295 ++++++ .../micode/notes/tool/GTaskStringUtils.java | 113 +++ .../net/micode/notes/tool/ResourceParser.java | 181 ++++ .../micode/notes/ui/AlarmAlertActivity.java | 158 +++ .../micode/notes/ui/AlarmInitReceiver.java | 65 ++ .../net/micode/notes/ui/AlarmReceiver.java | 30 + .../net/micode/notes/ui/DateTimePicker.java | 485 +++++++++ .../micode/notes/ui/DateTimePickerDialog.java | 90 ++ .../net/micode/notes/ui/DropdownMenu.java | 61 ++ .../micode/notes/ui/FoldersListAdapter.java | 80 ++ .../net/micode/notes/ui/NoteEditActivity.java | 873 ++++++++++++++++ .../net/micode/notes/ui/NoteEditText.java | 217 ++++ .../net/micode/notes/ui/NoteItemData.java | 224 ++++ .../micode/notes/ui/NotesListActivity.java | 954 ++++++++++++++++++ .../net/micode/notes/ui/NotesListAdapter.java | 184 ++++ .../net/micode/notes/ui/NotesListItem.java | 122 +++ .../notes/ui/NotesPreferenceActivity.java | 388 +++++++ .../notes/widget/NoteWidgetProvider.java | 132 +++ .../notes/widget/NoteWidgetProvider_2x.java | 47 + .../notes/widget/NoteWidgetProvider_4x.java | 46 + .../app/src/main/AndroidManifest.xml | 134 +-- .../notes/gtask/remote/GTaskASyncTask.java | 54 +- .../micode/notes/ui/AlarmAlertActivity.java | 66 +- .../micode/notes/ui/AlarmInitReceiver.java | 16 +- .../net/micode/notes/ui/AlarmReceiver.java | 6 +- .../net/micode/notes/ui/DateTimePicker.java | 63 +- .../net/micode/notes/ui/DropdownMenu.java | 13 +- .../micode/notes/ui/FoldersListAdapter.java | 23 +- .../net/micode/notes/ui/NoteEditActivity.java | 287 +----- .../app/src/main/res/layout/activity_main.xml | 173 +++- .../java/net/micode/notes/data/Contact.java | 73 ++ .../java/net/micode/notes/data/Notes.java | 279 +++++ .../notes/data/NotesDatabaseHelper.java | 362 +++++++ .../net/micode/notes/data/NotesProvider.java | 305 ++++++ .../net/micode/notes/gtask/data/MetaData.java | 82 ++ .../net/micode/notes/gtask/data/Node.java | 101 ++ .../net/micode/notes/gtask/data/SqlData.java | 189 ++++ .../net/micode/notes/gtask/data/SqlNote.java | 505 +++++++++ .../net/micode/notes/gtask/data/Task.java | 351 +++++++ .../net/micode/notes/gtask/data/TaskList.java | 343 +++++++ .../exception/ActionFailureException.java | 33 + .../exception/NetworkFailureException.java | 33 + .../notes/gtask/remote/GTaskASyncTask.java | 143 +++ .../notes/gtask/remote/GTaskClient.java | 585 +++++++++++ .../notes/gtask/remote/GTaskManager.java | 800 +++++++++++++++ .../notes/gtask/remote/GTaskSyncService.java | 128 +++ .../java/net/micode/notes/model/Note.java | 253 +++++ .../net/micode/notes/model/WorkingNote.java | 368 +++++++ .../net/micode/notes/tool/BackupUtils.java | 344 +++++++ .../java/net/micode/notes/tool/DataUtils.java | 295 ++++++ .../micode/notes/tool/GTaskStringUtils.java | 113 +++ .../net/micode/notes/tool/ResourceParser.java | 181 ++++ .../micode/notes/ui/AlarmAlertActivity.java | 158 +++ .../micode/notes/ui/AlarmInitReceiver.java | 65 ++ .../net/micode/notes/ui/AlarmReceiver.java | 30 + .../net/micode/notes/ui/DateTimePicker.java | 485 +++++++++ .../micode/notes/ui/DateTimePickerDialog.java | 90 ++ .../net/micode/notes/ui/DropdownMenu.java | 61 ++ .../micode/notes/ui/FoldersListAdapter.java | 80 ++ .../net/micode/notes/ui/NoteEditActivity.java | 873 ++++++++++++++++ .../net/micode/notes/ui/NoteEditText.java | 217 ++++ .../net/micode/notes/ui/NoteItemData.java | 224 ++++ .../micode/notes/ui/NotesListActivity.java | 954 ++++++++++++++++++ .../net/micode/notes/ui/NotesListAdapter.java | 184 ++++ .../net/micode/notes/ui/NotesListItem.java | 122 +++ .../notes/ui/NotesPreferenceActivity.java | 388 +++++++ .../notes/widget/NoteWidgetProvider.java | 132 +++ .../notes/widget/NoteWidgetProvider_2x.java | 47 + .../notes/widget/NoteWidgetProvider_4x.java | 46 + src/Notesmaster/gradle.properties | 2 +- src/Notesmaster/gradle/libs.versions.toml | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 4 +- 96 files changed, 20331 insertions(+), 571 deletions(-) rename doc/{bd4a5873bb8315d9b6741eee3eaea95.jpg => 5521ad1a33aaae1d739e2693e4c0152.jpg} (100%) delete mode 100644 doc/912646d2f6d177b304c182a20c4e9d8.png delete mode 100644 doc/小米便签开源代码的泛读报告111.docx create mode 100644 src/Notesmaster/.idea/vcs.xml create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Contact.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Notes.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesDatabaseHelper.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesProvider.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/MetaData.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Node.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlData.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlNote.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Task.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/TaskList.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/ActionFailureException.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/NetworkFailureException.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskASyncTask.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskClient.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskManager.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskSyncService.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/Note.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/WorkingNote.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/BackupUtils.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/DataUtils.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/GTaskStringUtils.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/ResourceParser.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmAlertActivity.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmInitReceiver.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmReceiver.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePicker.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePickerDialog.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DropdownMenu.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/FoldersListAdapter.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditActivity.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditText.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteItemData.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListActivity.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListAdapter.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListItem.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesPreferenceActivity.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_2x.java create mode 100644 src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_4x.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/data/Contact.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/data/Notes.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesDatabaseHelper.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesProvider.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/MetaData.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Node.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlData.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlNote.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Task.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/TaskList.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/ActionFailureException.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/NetworkFailureException.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskASyncTask.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskClient.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskManager.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskSyncService.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/model/Note.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/model/WorkingNote.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/tool/BackupUtils.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/tool/DataUtils.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/tool/GTaskStringUtils.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/tool/ResourceParser.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmAlertActivity.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmInitReceiver.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmReceiver.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePicker.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePickerDialog.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/DropdownMenu.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/FoldersListAdapter.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditActivity.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditText.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteItemData.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListActivity.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListAdapter.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListItem.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesPreferenceActivity.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_2x.java create mode 100644 src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_4x.java diff --git a/doc/bd4a5873bb8315d9b6741eee3eaea95.jpg b/doc/5521ad1a33aaae1d739e2693e4c0152.jpg similarity index 100% rename from doc/bd4a5873bb8315d9b6741eee3eaea95.jpg rename to doc/5521ad1a33aaae1d739e2693e4c0152.jpg diff --git a/doc/912646d2f6d177b304c182a20c4e9d8.png b/doc/912646d2f6d177b304c182a20c4e9d8.png deleted file mode 100644 index 8a256c34c84a9fcd91467f0959caa252d545f8f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 598255 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 z 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
  • 6*VI4>iJ<4NR(6mi; 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

    uuw}GTUgMYWUnS%v#8FM^9tIN=OUEa7HqN$fX%m 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

    rb}f0BVAwqs5T;s^G4|dS##=%ga(H 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

    wk-!5xA$m!7 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

    CWPm-t+%OKd>(xmX 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 a-;)F#4FYiV1Hf#d0uTfM(Bz99x&H$y3`;Zs diff --git a/src/Notesmaster/.idea/vcs.xml b/src/Notesmaster/.idea/vcs.xml new file mode 100644 index 0000000..69de57a --- /dev/null +++ b/src/Notesmaster/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Notesmaster/app/build.gradle.kts b/src/Notesmaster/app/build.gradle.kts index 6475e37..93647b0 100644 --- a/src/Notesmaster/app/build.gradle.kts +++ b/src/Notesmaster/app/build.gradle.kts @@ -3,13 +3,6 @@ plugins { } android { - packaging { - resources.excludes.add("META-INF/DEPENDENCIES"); - resources.excludes.add("META-INF/NOTICE"); - resources.excludes.add("META-INF/LICENSE"); - resources.excludes.add("META-INF/LICENSE.txt"); - resources.excludes.add("META-INF/NOTICE.txt"); - } namespace = "net.micode.notes" compileSdk = 34 @@ -33,8 +26,15 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + packaging { + resources.excludes.add("META-INF/DEPENDENCIES"); + resources.excludes.add("META-INF/NOTICE"); + resources.excludes.add("META-INF/LICENSE"); + resources.excludes.add("META-INF/LICENSE.txt"); + resources.excludes.add("META-INF/NOTICE.txt"); } } @@ -44,9 +44,14 @@ dependencies { implementation(libs.material) implementation(libs.activity) implementation(libs.constraintlayout) - implementation(files("D:\\Code\\AndroidCode\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-osgi-4.5.14.jar")) - implementation(files("D:\\Code\\AndroidCode\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-win-4.5.14.jar")) - implementation(files("D:\\Code\\AndroidCode\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpcore-4.4.16.jar")) +// implementation(fileTree(mapOf( +// "dir" to "D:\\Android Studio\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib", +// "include" to listOf("*.aar", "*.jar"), +// "exclude" to listOf("") + // ))) + implementation(files("D:\\Android Studio\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-osgi-4.5.14.jar")) + implementation(files("D:\\Android Studio\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-win-4.5.14.jar")) + implementation(files("D:\\Android Studio\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpcore-4.4.16.jar")) testImplementation(libs.junit) androidTestImplementation(libs.ext.junit) androidTestImplementation(libs.espresso.core) diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Contact.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Contact.java new file mode 100644 index 0000000..d97ac5d --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Contact.java @@ -0,0 +1,73 @@ +/* + * 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.data; + +import android.content.Context; +import android.database.Cursor; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.Data; +import android.telephony.PhoneNumberUtils; +import android.util.Log; + +import java.util.HashMap; + +public class Contact { + private static HashMap sContactCache; + private static final String TAG = "Contact"; + + private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER + + ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'" + + " AND " + Data.RAW_CONTACT_ID + " IN " + + "(SELECT raw_contact_id " + + " FROM phone_lookup" + + " WHERE min_match = '+')"; + + public static String getContact(Context context, String phoneNumber) { + if(sContactCache == null) { + sContactCache = new HashMap(); + } + + if(sContactCache.containsKey(phoneNumber)) { + return sContactCache.get(phoneNumber); + } + + String selection = CALLER_ID_SELECTION.replace("+", + PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)); + Cursor cursor = context.getContentResolver().query( + Data.CONTENT_URI, + new String [] { Phone.DISPLAY_NAME }, + selection, + new String[] { phoneNumber }, + null); + + if (cursor != null && cursor.moveToFirst()) { + try { + String name = cursor.getString(0); + sContactCache.put(phoneNumber, name); + return name; + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, " Cursor get string error " + e.toString()); + return null; + } finally { + cursor.close(); + } + } else { + Log.d(TAG, "No contact matched with number:" + phoneNumber); + return null; + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Notes.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Notes.java new file mode 100644 index 0000000..f240604 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/Notes.java @@ -0,0 +1,279 @@ +/* + * 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.data; + +import android.net.Uri; +public class Notes { + public static final String AUTHORITY = "micode_notes"; + public static final String TAG = "Notes"; + public static final int TYPE_NOTE = 0; + public static final int TYPE_FOLDER = 1; + public static final int TYPE_SYSTEM = 2; + + /** + * Following IDs are system folders' identifiers + * {@link Notes#ID_ROOT_FOLDER } is default folder + * {@link Notes#ID_TEMPARAY_FOLDER } is for notes belonging no folder + * {@link Notes#ID_CALL_RECORD_FOLDER} is to store call records + */ + public static final int ID_ROOT_FOLDER = 0; + public static final int ID_TEMPARAY_FOLDER = -1; + public static final int ID_CALL_RECORD_FOLDER = -2; + public static final int ID_TRASH_FOLER = -3; + + public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date"; + public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id"; + public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id"; + public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type"; + public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id"; + public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date"; + + public static final int TYPE_WIDGET_INVALIDE = -1; + public static final int TYPE_WIDGET_2X = 0; + public static final int TYPE_WIDGET_4X = 1; + + public static class DataConstants { + public static final String NOTE = TextNote.CONTENT_ITEM_TYPE; + public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE; + } + + /** + * Uri to query all notes and folders + */ + public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note"); + + /** + * Uri to query data + */ + public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data"); + + public interface NoteColumns { + /** + * The unique ID for a row + *

    Type: INTEGER (long)

    + */ + public static final String ID = "_id"; + + /** + * The parent's id for note or folder + *

    Type: INTEGER (long)

    + */ + public static final String PARENT_ID = "parent_id"; + + /** + * Created data for note or folder + *

    Type: INTEGER (long)

    + */ + public static final String CREATED_DATE = "created_date"; + + /** + * Latest modified date + *

    Type: INTEGER (long)

    + */ + public static final String MODIFIED_DATE = "modified_date"; + + + /** + * Alert date + *

    Type: INTEGER (long)

    + */ + public static final String ALERTED_DATE = "alert_date"; + + /** + * Folder's name or text content of note + *

    Type: TEXT

    + */ + public static final String SNIPPET = "snippet"; + + /** + * Note's widget id + *

    Type: INTEGER (long)

    + */ + public static final String WIDGET_ID = "widget_id"; + + /** + * Note's widget type + *

    Type: INTEGER (long)

    + */ + public static final String WIDGET_TYPE = "widget_type"; + + /** + * Note's background color's id + *

    Type: INTEGER (long)

    + */ + public static final String BG_COLOR_ID = "bg_color_id"; + + /** + * For text note, it doesn't has attachment, for multi-media + * note, it has at least one attachment + *

    Type: INTEGER

    + */ + public static final String HAS_ATTACHMENT = "has_attachment"; + + /** + * Folder's count of notes + *

    Type: INTEGER (long)

    + */ + public static final String NOTES_COUNT = "notes_count"; + + /** + * The file type: folder or note + *

    Type: INTEGER

    + */ + public static final String TYPE = "type"; + + /** + * The last sync id + *

    Type: INTEGER (long)

    + */ + public static final String SYNC_ID = "sync_id"; + + /** + * Sign to indicate local modified or not + *

    Type: INTEGER

    + */ + public static final String LOCAL_MODIFIED = "local_modified"; + + /** + * Original parent id before moving into temporary folder + *

    Type : INTEGER

    + */ + public static final String ORIGIN_PARENT_ID = "origin_parent_id"; + + /** + * The gtask id + *

    Type : TEXT

    + */ + public static final String GTASK_ID = "gtask_id"; + + /** + * The version code + *

    Type : INTEGER (long)

    + */ + public static final String VERSION = "version"; + } + + public interface DataColumns { + /** + * The unique ID for a row + *

    Type: INTEGER (long)

    + */ + public static final String ID = "_id"; + + /** + * The MIME type of the item represented by this row. + *

    Type: Text

    + */ + public static final String MIME_TYPE = "mime_type"; + + /** + * The reference id to note that this data belongs to + *

    Type: INTEGER (long)

    + */ + public static final String NOTE_ID = "note_id"; + + /** + * Created data for note or folder + *

    Type: INTEGER (long)

    + */ + public static final String CREATED_DATE = "created_date"; + + /** + * Latest modified date + *

    Type: INTEGER (long)

    + */ + public static final String MODIFIED_DATE = "modified_date"; + + /** + * Data's content + *

    Type: TEXT

    + */ + public static final String CONTENT = "content"; + + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * integer data type + *

    Type: INTEGER

    + */ + public static final String DATA1 = "data1"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * integer data type + *

    Type: INTEGER

    + */ + public static final String DATA2 = "data2"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *

    Type: TEXT

    + */ + public static final String DATA3 = "data3"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *

    Type: TEXT

    + */ + public static final String DATA4 = "data4"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *

    Type: TEXT

    + */ + public static final String DATA5 = "data5"; + } + + public static final class TextNote implements DataColumns { + /** + * Mode to indicate the text in check list mode or not + *

    Type: Integer 1:check list mode 0: normal mode

    + */ + public static final String MODE = DATA1; + + public static final int MODE_CHECK_LIST = 1; + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note"; + + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note"; + + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note"); + } + + public static final class CallNote implements DataColumns { + /** + * Call date for this record + *

    Type: INTEGER (long)

    + */ + public static final String CALL_DATE = DATA1; + + /** + * Phone number for this record + *

    Type: TEXT

    + */ + public static final String PHONE_NUMBER = DATA3; + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note"; + + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note"; + + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note"); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesDatabaseHelper.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesDatabaseHelper.java new file mode 100644 index 0000000..ffe5d57 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesDatabaseHelper.java @@ -0,0 +1,362 @@ +/* + * 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.data; + +import android.content.ContentValues; +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.DataConstants; +import net.micode.notes.data.Notes.NoteColumns; + + +public class NotesDatabaseHelper extends SQLiteOpenHelper { + private static final String DB_NAME = "note.db"; + + private static final int DB_VERSION = 4; + + public interface TABLE { + public static final String NOTE = "note"; + + public static final String DATA = "data"; + } + + private static final String TAG = "NotesDatabaseHelper"; + + private static NotesDatabaseHelper mInstance; + + private static final String CREATE_NOTE_TABLE_SQL = + "CREATE TABLE " + TABLE.NOTE + "(" + + NoteColumns.ID + " INTEGER PRIMARY KEY," + + NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," + + NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," + + NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," + + NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" + + ")"; + + private static final String CREATE_DATA_TABLE_SQL = + "CREATE TABLE " + TABLE.DATA + "(" + + DataColumns.ID + " INTEGER PRIMARY KEY," + + DataColumns.MIME_TYPE + " TEXT NOT NULL," + + DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA1 + " INTEGER," + + DataColumns.DATA2 + " INTEGER," + + DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" + + ")"; + + private static final String CREATE_DATA_NOTE_ID_INDEX_SQL = + "CREATE INDEX IF NOT EXISTS note_id_index ON " + + TABLE.DATA + "(" + DataColumns.NOTE_ID + ");"; + + /** + * Increase folder's note count when move note to the folder + */ + private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER increase_folder_count_on_update "+ + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + + " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + + " END"; + + /** + * Decrease folder's note count when move note from folder + */ + private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER decrease_folder_count_on_update " + + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" + + " END"; + + /** + * Increase folder's note count when insert new note to the folder + */ + private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER = + "CREATE TRIGGER increase_folder_count_on_insert " + + " AFTER INSERT ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + + " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + + " END"; + + /** + * Decrease folder's note count when delete note from the folder + */ + private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER = + "CREATE TRIGGER decrease_folder_count_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0;" + + " END"; + + /** + * Update note's content when insert data with type {@link DataConstants#NOTE} + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER = + "CREATE TRIGGER update_note_content_on_insert " + + " AFTER INSERT ON " + TABLE.DATA + + " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Update note's content when data with {@link DataConstants#NOTE} type has changed + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER update_note_content_on_update " + + " AFTER UPDATE ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Update note's content when data with {@link DataConstants#NOTE} type has deleted + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER = + "CREATE TRIGGER update_note_content_on_delete " + + " AFTER delete ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=''" + + " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Delete datas belong to note which has been deleted + */ + private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER = + "CREATE TRIGGER delete_data_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.DATA + + " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + /** + * Delete notes belong to folder which has been deleted + */ + private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER = + "CREATE TRIGGER folder_delete_notes_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + /** + * Move notes belong to folder which has been moved to trash folder + */ + private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER = + "CREATE TRIGGER folder_move_notes_on_trash " + + " AFTER UPDATE ON " + TABLE.NOTE + + " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + public NotesDatabaseHelper(Context context) { + super(context, DB_NAME, null, DB_VERSION); + } + + public void createNoteTable(SQLiteDatabase db) { + db.execSQL(CREATE_NOTE_TABLE_SQL); + reCreateNoteTableTriggers(db); + createSystemFolder(db); + Log.d(TAG, "note table has been created"); + } + + private void reCreateNoteTableTriggers(SQLiteDatabase db) { + db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS delete_data_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS folder_delete_notes_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS folder_move_notes_on_trash"); + + db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); + db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); + db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER); + db.execSQL(NOTE_DELETE_DATA_ON_DELETE_TRIGGER); + db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER); + db.execSQL(FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER); + db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER); + } + + private void createSystemFolder(SQLiteDatabase db) { + ContentValues values = new ContentValues(); + + /** + * call record foler for call notes + */ + values.put(NoteColumns.ID, Notes.ID_CALL_RECORD_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * root folder which is default folder + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * temporary folder which is used for moving note + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * create trash folder + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + } + + public void createDataTable(SQLiteDatabase db) { + db.execSQL(CREATE_DATA_TABLE_SQL); + reCreateDataTableTriggers(db); + db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL); + Log.d(TAG, "data table has been created"); + } + + private void reCreateDataTableTriggers(SQLiteDatabase db) { + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_delete"); + + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER); + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER); + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER); + } + + static synchronized NotesDatabaseHelper getInstance(Context context) { + if (mInstance == null) { + mInstance = new NotesDatabaseHelper(context); + } + return mInstance; + } + + @Override + public void onCreate(SQLiteDatabase db) { + createNoteTable(db); + createDataTable(db); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + boolean reCreateTriggers = false; + boolean skipV2 = false; + + if (oldVersion == 1) { + upgradeToV2(db); + skipV2 = true; // this upgrade including the upgrade from v2 to v3 + oldVersion++; + } + + if (oldVersion == 2 && !skipV2) { + upgradeToV3(db); + reCreateTriggers = true; + oldVersion++; + } + + if (oldVersion == 3) { + upgradeToV4(db); + oldVersion++; + } + + if (reCreateTriggers) { + reCreateNoteTableTriggers(db); + reCreateDataTableTriggers(db); + } + + if (oldVersion != newVersion) { + throw new IllegalStateException("Upgrade notes database to version " + newVersion + + "fails"); + } + } + + private void upgradeToV2(SQLiteDatabase db) { + db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); + db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA); + createNoteTable(db); + createDataTable(db); + } + + private void upgradeToV3(SQLiteDatabase db) { + // drop unused triggers + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_update"); + // add a column for gtask id + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.GTASK_ID + + " TEXT NOT NULL DEFAULT ''"); + // add a trash system folder + ContentValues values = new ContentValues(); + values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + } + + private void upgradeToV4(SQLiteDatabase db) { + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION + + " INTEGER NOT NULL DEFAULT 0"); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesProvider.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesProvider.java new file mode 100644 index 0000000..edb0a60 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/data/NotesProvider.java @@ -0,0 +1,305 @@ +/* + * 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.data; + + +import android.app.SearchManager; +import android.content.ContentProvider; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Intent; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Log; + +import net.micode.notes.R; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.data.NotesDatabaseHelper.TABLE; + + +public class NotesProvider extends ContentProvider { + private static final UriMatcher mMatcher; + + private NotesDatabaseHelper mHelper; + + private static final String TAG = "NotesProvider"; + + private static final int URI_NOTE = 1; + private static final int URI_NOTE_ITEM = 2; + private static final int URI_DATA = 3; + private static final int URI_DATA_ITEM = 4; + + private static final int URI_SEARCH = 5; + private static final int URI_SEARCH_SUGGEST = 6; + + static { + mMatcher = new UriMatcher(UriMatcher.NO_MATCH); + mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); + mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); + mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); + mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); + mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST); + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST); + } + + /** + * x'0A' represents the '\n' character in sqlite. For title and content in the search result, + * we will trim '\n' and white space in order to show more information. + */ + private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," + + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + "," + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + "," + + R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + "," + + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," + + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; + + private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION + + " FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.SNIPPET + " LIKE ?" + + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE; + + @Override + public boolean onCreate() { + mHelper = NotesDatabaseHelper.getInstance(getContext()); + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + Cursor c = null; + SQLiteDatabase db = mHelper.getReadableDatabase(); + String id = null; + switch (mMatcher.match(uri)) { + case URI_NOTE: + c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, + sortOrder); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id + + parseSelection(selection), selectionArgs, null, null, sortOrder); + break; + case URI_DATA: + c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null, + sortOrder); + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs, null, null, sortOrder); + break; + case URI_SEARCH: + case URI_SEARCH_SUGGEST: + if (sortOrder != null || projection != null) { + throw new IllegalArgumentException( + "do not specify sortOrder, selection, selectionArgs, or projection" + "with this query"); + } + + String searchString = null; + if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) { + if (uri.getPathSegments().size() > 1) { + searchString = uri.getPathSegments().get(1); + } + } else { + searchString = uri.getQueryParameter("pattern"); + } + + if (TextUtils.isEmpty(searchString)) { + return null; + } + + try { + searchString = String.format("%%%s%%", searchString); + c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, + new String[] { searchString }); + } catch (IllegalStateException ex) { + Log.e(TAG, "got exception: " + ex.toString()); + } + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + if (c != null) { + c.setNotificationUri(getContext().getContentResolver(), uri); + } + return c; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + SQLiteDatabase db = mHelper.getWritableDatabase(); + long dataId = 0, noteId = 0, insertedId = 0; + switch (mMatcher.match(uri)) { + case URI_NOTE: + insertedId = noteId = db.insert(TABLE.NOTE, null, values); + break; + case URI_DATA: + if (values.containsKey(DataColumns.NOTE_ID)) { + noteId = values.getAsLong(DataColumns.NOTE_ID); + } else { + Log.d(TAG, "Wrong data format without note id:" + values.toString()); + } + insertedId = dataId = db.insert(TABLE.DATA, null, values); + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + // Notify the note uri + if (noteId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null); + } + + // Notify the data uri + if (dataId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); + } + + return ContentUris.withAppendedId(uri, insertedId); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + int count = 0; + String id = null; + SQLiteDatabase db = mHelper.getWritableDatabase(); + boolean deleteData = false; + switch (mMatcher.match(uri)) { + case URI_NOTE: + selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; + count = db.delete(TABLE.NOTE, selection, selectionArgs); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + /** + * ID that smaller than 0 is system folder which is not allowed to + * trash + */ + long noteId = Long.valueOf(id); + if (noteId <= 0) { + break; + } + count = db.delete(TABLE.NOTE, + NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); + break; + case URI_DATA: + count = db.delete(TABLE.DATA, selection, selectionArgs); + deleteData = true; + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + count = db.delete(TABLE.DATA, + DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); + deleteData = true; + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + if (count > 0) { + if (deleteData) { + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + getContext().getContentResolver().notifyChange(uri, null); + } + return count; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + int count = 0; + String id = null; + SQLiteDatabase db = mHelper.getWritableDatabase(); + boolean updateData = false; + switch (mMatcher.match(uri)) { + case URI_NOTE: + increaseNoteVersion(-1, selection, selectionArgs); + count = db.update(TABLE.NOTE, values, selection, selectionArgs); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); + count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id + + parseSelection(selection), selectionArgs); + break; + case URI_DATA: + count = db.update(TABLE.DATA, values, selection, selectionArgs); + updateData = true; + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs); + updateData = true; + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + + if (count > 0) { + if (updateData) { + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + getContext().getContentResolver().notifyChange(uri, null); + } + return count; + } + + private String parseSelection(String selection) { + return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); + } + + private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { + StringBuilder sql = new StringBuilder(120); + sql.append("UPDATE "); + sql.append(TABLE.NOTE); + sql.append(" SET "); + sql.append(NoteColumns.VERSION); + sql.append("=" + NoteColumns.VERSION + "+1 "); + + if (id > 0 || !TextUtils.isEmpty(selection)) { + sql.append(" WHERE "); + } + if (id > 0) { + sql.append(NoteColumns.ID + "=" + String.valueOf(id)); + } + if (!TextUtils.isEmpty(selection)) { + String selectString = id > 0 ? parseSelection(selection) : selection; + for (String args : selectionArgs) { + selectString = selectString.replaceFirst("\\?", args); + } + sql.append(selectString); + } + + mHelper.getWritableDatabase().execSQL(sql.toString()); + } + + @Override + public String getType(Uri uri) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/MetaData.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/MetaData.java new file mode 100644 index 0000000..3a2050b --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/MetaData.java @@ -0,0 +1,82 @@ +/* + * 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.database.Cursor; +import android.util.Log; + +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class MetaData extends Task { + private final static String TAG = MetaData.class.getSimpleName(); + + private String mRelatedGid = null; + + public void setMeta(String gid, JSONObject metaInfo) { + try { + metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); + } catch (JSONException e) { + Log.e(TAG, "failed to put related gid"); + } + setNotes(metaInfo.toString()); + setName(GTaskStringUtils.META_NOTE_NAME); + } + + public String getRelatedGid() { + return mRelatedGid; + } + + @Override + public boolean isWorthSaving() { + return getNotes() != null; + } + + @Override + public void setContentByRemoteJSON(JSONObject js) { + super.setContentByRemoteJSON(js); + if (getNotes() != null) { + try { + JSONObject metaInfo = new JSONObject(getNotes().trim()); + mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); + } catch (JSONException e) { + Log.w(TAG, "failed to get related gid"); + mRelatedGid = null; + } + } + } + + @Override + public void setContentByLocalJSON(JSONObject js) { + // this function should not be called + throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); + } + + @Override + public JSONObject getLocalJSONFromContent() { + throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); + } + + @Override + public int getSyncAction(Cursor c) { + throw new IllegalAccessError("MetaData:getSyncAction should not be called"); + } + +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Node.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Node.java new file mode 100644 index 0000000..63950e0 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Node.java @@ -0,0 +1,101 @@ +/* + * 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.database.Cursor; + +import org.json.JSONObject; + +public abstract class Node { + public static final int SYNC_ACTION_NONE = 0; + + public static final int SYNC_ACTION_ADD_REMOTE = 1; + + public static final int SYNC_ACTION_ADD_LOCAL = 2; + + public static final int SYNC_ACTION_DEL_REMOTE = 3; + + public static final int SYNC_ACTION_DEL_LOCAL = 4; + + public static final int SYNC_ACTION_UPDATE_REMOTE = 5; + + public static final int SYNC_ACTION_UPDATE_LOCAL = 6; + + public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; + + public static final int SYNC_ACTION_ERROR = 8; + + private String mGid; + + private String mName; + + private long mLastModified; + + private boolean mDeleted; + + public Node() { + mGid = null; + mName = ""; + mLastModified = 0; + mDeleted = false; + } + + public abstract JSONObject getCreateAction(int actionId); + + public abstract JSONObject getUpdateAction(int actionId); + + public abstract void setContentByRemoteJSON(JSONObject js); + + public abstract void setContentByLocalJSON(JSONObject js); + + public abstract JSONObject getLocalJSONFromContent(); + + public abstract int getSyncAction(Cursor c); + + public void setGid(String gid) { + this.mGid = gid; + } + + public void setName(String name) { + this.mName = name; + } + + public void setLastModified(long lastModified) { + this.mLastModified = lastModified; + } + + public void setDeleted(boolean deleted) { + this.mDeleted = deleted; + } + + public String getGid() { + return this.mGid; + } + + public String getName() { + return this.mName; + } + + public long getLastModified() { + return this.mLastModified; + } + + public boolean getDeleted() { + return this.mDeleted; + } + +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlData.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlData.java new file mode 100644 index 0000000..d3ec3be --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlData.java @@ -0,0 +1,189 @@ +/* + * 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.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +import net.micode.notes.data.Notes; +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.NotesDatabaseHelper.TABLE; +import net.micode.notes.gtask.exception.ActionFailureException; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class SqlData { + private static final String TAG = SqlData.class.getSimpleName(); + + private static final int INVALID_ID = -99999; + + public static final String[] PROJECTION_DATA = new String[] { + DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, + DataColumns.DATA3 + }; + + public static final int DATA_ID_COLUMN = 0; + + public static final int DATA_MIME_TYPE_COLUMN = 1; + + public static final int DATA_CONTENT_COLUMN = 2; + + public static final int DATA_CONTENT_DATA_1_COLUMN = 3; + + public static final int DATA_CONTENT_DATA_3_COLUMN = 4; + + private ContentResolver mContentResolver; + + private boolean mIsCreate; + + private long mDataId; + + private String mDataMimeType; + + private String mDataContent; + + private long mDataContentData1; + + private String mDataContentData3; + + private ContentValues mDiffDataValues; + + public SqlData(Context context) { + mContentResolver = context.getContentResolver(); + mIsCreate = true; + mDataId = INVALID_ID; + mDataMimeType = DataConstants.NOTE; + mDataContent = ""; + mDataContentData1 = 0; + mDataContentData3 = ""; + mDiffDataValues = new ContentValues(); + } + + public SqlData(Context context, Cursor c) { + mContentResolver = context.getContentResolver(); + mIsCreate = false; + loadFromCursor(c); + mDiffDataValues = new ContentValues(); + } + + private void loadFromCursor(Cursor c) { + mDataId = c.getLong(DATA_ID_COLUMN); + mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); + mDataContent = c.getString(DATA_CONTENT_COLUMN); + mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); + mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); + } + + public void setContent(JSONObject js) throws JSONException { + long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; + if (mIsCreate || mDataId != dataId) { + mDiffDataValues.put(DataColumns.ID, dataId); + } + mDataId = dataId; + + String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE) + : DataConstants.NOTE; + if (mIsCreate || !mDataMimeType.equals(dataMimeType)) { + mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); + } + mDataMimeType = dataMimeType; + + String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : ""; + if (mIsCreate || !mDataContent.equals(dataContent)) { + mDiffDataValues.put(DataColumns.CONTENT, dataContent); + } + mDataContent = dataContent; + + long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0; + if (mIsCreate || mDataContentData1 != dataContentData1) { + mDiffDataValues.put(DataColumns.DATA1, dataContentData1); + } + mDataContentData1 = dataContentData1; + + String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : ""; + if (mIsCreate || !mDataContentData3.equals(dataContentData3)) { + mDiffDataValues.put(DataColumns.DATA3, dataContentData3); + } + mDataContentData3 = dataContentData3; + } + + public JSONObject getContent() throws JSONException { + if (mIsCreate) { + Log.e(TAG, "it seems that we haven't created this in database yet"); + return null; + } + JSONObject js = new JSONObject(); + js.put(DataColumns.ID, mDataId); + js.put(DataColumns.MIME_TYPE, mDataMimeType); + js.put(DataColumns.CONTENT, mDataContent); + js.put(DataColumns.DATA1, mDataContentData1); + js.put(DataColumns.DATA3, mDataContentData3); + return js; + } + + public void commit(long noteId, boolean validateVersion, long version) { + + if (mIsCreate) { + if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { + mDiffDataValues.remove(DataColumns.ID); + } + + mDiffDataValues.put(DataColumns.NOTE_ID, noteId); + Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); + try { + mDataId = Long.valueOf(uri.getPathSegments().get(1)); + } catch (NumberFormatException e) { + Log.e(TAG, "Get note id error :" + e.toString()); + throw new ActionFailureException("create note failed"); + } + } else { + if (mDiffDataValues.size() > 0) { + int result = 0; + if (!validateVersion) { + result = mContentResolver.update(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); + } else { + result = mContentResolver.update(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, + " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.VERSION + "=?)", new String[] { + String.valueOf(noteId), String.valueOf(version) + }); + } + if (result == 0) { + Log.w(TAG, "there is no update. maybe user updates note when syncing"); + } + } + } + + mDiffDataValues.clear(); + mIsCreate = false; + } + + public long getId() { + return mDataId; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlNote.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlNote.java new file mode 100644 index 0000000..79a4095 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/SqlNote.java @@ -0,0 +1,505 @@ +/* + * 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; +import android.database.Cursor; +import android.net.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; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + + +public class SqlNote { + private static final String TAG = SqlNote.class.getSimpleName(); + + private static final int INVALID_ID = -99999; + + public static final String[] PROJECTION_NOTE = new String[] { + NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, + NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE, + NoteColumns.NOTES_COUNT, NoteColumns.PARENT_ID, NoteColumns.SNIPPET, NoteColumns.TYPE, + NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, NoteColumns.SYNC_ID, + NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID, + NoteColumns.VERSION + }; + + public static final int ID_COLUMN = 0; + + public static final int ALERTED_DATE_COLUMN = 1; + + public static final int BG_COLOR_ID_COLUMN = 2; + + public static final int CREATED_DATE_COLUMN = 3; + + public static final int HAS_ATTACHMENT_COLUMN = 4; + + public static final int MODIFIED_DATE_COLUMN = 5; + + public static final int NOTES_COUNT_COLUMN = 6; + + public static final int PARENT_ID_COLUMN = 7; + + public static final int SNIPPET_COLUMN = 8; + + public static final int TYPE_COLUMN = 9; + + public static final int WIDGET_ID_COLUMN = 10; + + public static final int WIDGET_TYPE_COLUMN = 11; + + public static final int SYNC_ID_COLUMN = 12; + + public static final int LOCAL_MODIFIED_COLUMN = 13; + + public static final int ORIGIN_PARENT_ID_COLUMN = 14; + + public static final int GTASK_ID_COLUMN = 15; + + public static final int VERSION_COLUMN = 16; + + private Context mContext; + + private ContentResolver mContentResolver; + + private boolean mIsCreate; + + private long mId; + + private long mAlertDate; + + private int mBgColorId; + + private long mCreatedDate; + + private int mHasAttachment; + + private long mModifiedDate; + + private long mParentId; + + private String mSnippet; + + private int mType; + + private int mWidgetId; + + private int mWidgetType; + + private long mOriginParent; + + private long mVersion; + + private ContentValues mDiffNoteValues; + + private ArrayList mDataList; + + public SqlNote(Context context) { + mContext = context; + mContentResolver = context.getContentResolver(); + mIsCreate = true; + mId = INVALID_ID; + mAlertDate = 0; + mBgColorId = ResourceParser.getDefaultBgId(context); + mCreatedDate = System.currentTimeMillis(); + mHasAttachment = 0; + mModifiedDate = System.currentTimeMillis(); + mParentId = 0; + mSnippet = ""; + mType = Notes.TYPE_NOTE; + mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; + mWidgetType = Notes.TYPE_WIDGET_INVALIDE; + mOriginParent = 0; + mVersion = 0; + mDiffNoteValues = new ContentValues(); + mDataList = new ArrayList(); + } + + public SqlNote(Context context, Cursor c) { + mContext = context; + mContentResolver = context.getContentResolver(); + mIsCreate = false; + loadFromCursor(c); + mDataList = new ArrayList(); + if (mType == Notes.TYPE_NOTE) + loadDataContent(); + mDiffNoteValues = new ContentValues(); + } + + public SqlNote(Context context, long id) { + mContext = context; + mContentResolver = context.getContentResolver(); + mIsCreate = false; + loadFromCursor(id); + mDataList = new ArrayList(); + if (mType == Notes.TYPE_NOTE) + loadDataContent(); + mDiffNoteValues = new ContentValues(); + + } + + private void loadFromCursor(long id) { + Cursor c = null; + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)", + new String[] { + String.valueOf(id) + }, null); + if (c != null) { + c.moveToNext(); + loadFromCursor(c); + } else { + Log.w(TAG, "loadFromCursor: cursor = null"); + } + } finally { + if (c != null) + c.close(); + } + } + + private void loadFromCursor(Cursor c) { + mId = c.getLong(ID_COLUMN); + mAlertDate = c.getLong(ALERTED_DATE_COLUMN); + mBgColorId = c.getInt(BG_COLOR_ID_COLUMN); + mCreatedDate = c.getLong(CREATED_DATE_COLUMN); + mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN); + mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN); + mParentId = c.getLong(PARENT_ID_COLUMN); + mSnippet = c.getString(SNIPPET_COLUMN); + mType = c.getInt(TYPE_COLUMN); + mWidgetId = c.getInt(WIDGET_ID_COLUMN); + mWidgetType = c.getInt(WIDGET_TYPE_COLUMN); + mVersion = c.getLong(VERSION_COLUMN); + } + + private void loadDataContent() { + Cursor c = null; + mDataList.clear(); + try { + c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA, + "(note_id=?)", new String[] { + String.valueOf(mId) + }, null); + if (c != null) { + if (c.getCount() == 0) { + Log.w(TAG, "it seems that the note has not data"); + return; + } + while (c.moveToNext()) { + SqlData data = new SqlData(mContext, c); + mDataList.add(data); + } + } else { + Log.w(TAG, "loadDataContent: cursor = null"); + } + } finally { + if (c != null) + c.close(); + } + } + + public boolean setContent(JSONObject js) { + try { + JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { + Log.w(TAG, "cannot set system folder"); + } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { + // for folder we can only update the snnipet and type + String snippet = note.has(NoteColumns.SNIPPET) ? note + .getString(NoteColumns.SNIPPET) : ""; + if (mIsCreate || !mSnippet.equals(snippet)) { + mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); + } + mSnippet = snippet; + + int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) + : Notes.TYPE_NOTE; + if (mIsCreate || mType != type) { + mDiffNoteValues.put(NoteColumns.TYPE, type); + } + mType = type; + } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) { + JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); + long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID; + if (mIsCreate || mId != id) { + mDiffNoteValues.put(NoteColumns.ID, id); + } + mId = id; + + long alertDate = note.has(NoteColumns.ALERTED_DATE) ? note + .getLong(NoteColumns.ALERTED_DATE) : 0; + if (mIsCreate || mAlertDate != alertDate) { + mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate); + } + mAlertDate = alertDate; + + int bgColorId = note.has(NoteColumns.BG_COLOR_ID) ? note + .getInt(NoteColumns.BG_COLOR_ID) : ResourceParser.getDefaultBgId(mContext); + if (mIsCreate || mBgColorId != bgColorId) { + mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId); + } + mBgColorId = bgColorId; + + long createDate = note.has(NoteColumns.CREATED_DATE) ? note + .getLong(NoteColumns.CREATED_DATE) : System.currentTimeMillis(); + if (mIsCreate || mCreatedDate != createDate) { + mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate); + } + mCreatedDate = createDate; + + int hasAttachment = note.has(NoteColumns.HAS_ATTACHMENT) ? note + .getInt(NoteColumns.HAS_ATTACHMENT) : 0; + if (mIsCreate || mHasAttachment != hasAttachment) { + mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment); + } + mHasAttachment = hasAttachment; + + long modifiedDate = note.has(NoteColumns.MODIFIED_DATE) ? note + .getLong(NoteColumns.MODIFIED_DATE) : System.currentTimeMillis(); + if (mIsCreate || mModifiedDate != modifiedDate) { + mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate); + } + mModifiedDate = modifiedDate; + + long parentId = note.has(NoteColumns.PARENT_ID) ? note + .getLong(NoteColumns.PARENT_ID) : 0; + if (mIsCreate || mParentId != parentId) { + mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId); + } + mParentId = parentId; + + String snippet = note.has(NoteColumns.SNIPPET) ? note + .getString(NoteColumns.SNIPPET) : ""; + if (mIsCreate || !mSnippet.equals(snippet)) { + mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); + } + mSnippet = snippet; + + int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) + : Notes.TYPE_NOTE; + if (mIsCreate || mType != type) { + mDiffNoteValues.put(NoteColumns.TYPE, type); + } + mType = type; + + int widgetId = note.has(NoteColumns.WIDGET_ID) ? note.getInt(NoteColumns.WIDGET_ID) + : AppWidgetManager.INVALID_APPWIDGET_ID; + if (mIsCreate || mWidgetId != widgetId) { + mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId); + } + mWidgetId = widgetId; + + int widgetType = note.has(NoteColumns.WIDGET_TYPE) ? note + .getInt(NoteColumns.WIDGET_TYPE) : Notes.TYPE_WIDGET_INVALIDE; + if (mIsCreate || mWidgetType != widgetType) { + mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType); + } + mWidgetType = widgetType; + + long originParent = note.has(NoteColumns.ORIGIN_PARENT_ID) ? note + .getLong(NoteColumns.ORIGIN_PARENT_ID) : 0; + if (mIsCreate || mOriginParent != originParent) { + mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent); + } + mOriginParent = originParent; + + for (int i = 0; i < dataArray.length(); i++) { + JSONObject data = dataArray.getJSONObject(i); + SqlData sqlData = null; + if (data.has(DataColumns.ID)) { + long dataId = data.getLong(DataColumns.ID); + for (SqlData temp : mDataList) { + if (dataId == temp.getId()) { + sqlData = temp; + } + } + } + + if (sqlData == null) { + sqlData = new SqlData(mContext); + mDataList.add(sqlData); + } + + sqlData.setContent(data); + } + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return false; + } + return true; + } + + public JSONObject getContent() { + try { + JSONObject js = new JSONObject(); + + if (mIsCreate) { + Log.e(TAG, "it seems that we haven't created this in database yet"); + return null; + } + + JSONObject note = new JSONObject(); + if (mType == Notes.TYPE_NOTE) { + note.put(NoteColumns.ID, mId); + note.put(NoteColumns.ALERTED_DATE, mAlertDate); + note.put(NoteColumns.BG_COLOR_ID, mBgColorId); + note.put(NoteColumns.CREATED_DATE, mCreatedDate); + note.put(NoteColumns.HAS_ATTACHMENT, mHasAttachment); + note.put(NoteColumns.MODIFIED_DATE, mModifiedDate); + note.put(NoteColumns.PARENT_ID, mParentId); + note.put(NoteColumns.SNIPPET, mSnippet); + note.put(NoteColumns.TYPE, mType); + note.put(NoteColumns.WIDGET_ID, mWidgetId); + note.put(NoteColumns.WIDGET_TYPE, mWidgetType); + note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent); + js.put(GTaskStringUtils.META_HEAD_NOTE, note); + + JSONArray dataArray = new JSONArray(); + for (SqlData sqlData : mDataList) { + JSONObject data = sqlData.getContent(); + if (data != null) { + dataArray.put(data); + } + } + js.put(GTaskStringUtils.META_HEAD_DATA, dataArray); + } else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) { + note.put(NoteColumns.ID, mId); + note.put(NoteColumns.TYPE, mType); + note.put(NoteColumns.SNIPPET, mSnippet); + js.put(GTaskStringUtils.META_HEAD_NOTE, note); + } + + return js; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + return null; + } + + public void setParentId(long id) { + mParentId = id; + mDiffNoteValues.put(NoteColumns.PARENT_ID, id); + } + + public void setGtaskId(String gid) { + mDiffNoteValues.put(NoteColumns.GTASK_ID, gid); + } + + public void setSyncId(long syncId) { + mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId); + } + + public void resetLocalModified() { + mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0); + } + + public long getId() { + return mId; + } + + public long getParentId() { + return mParentId; + } + + public String getSnippet() { + return mSnippet; + } + + public boolean isNoteType() { + return mType == Notes.TYPE_NOTE; + } + + public void commit(boolean validateVersion) { + if (mIsCreate) { + if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) { + mDiffNoteValues.remove(NoteColumns.ID); + } + + Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues); + try { + mId = Long.valueOf(uri.getPathSegments().get(1)); + } catch (NumberFormatException e) { + Log.e(TAG, "Get note id error :" + e.toString()); + throw new ActionFailureException("create note failed"); + } + if (mId == 0) { + throw new IllegalStateException("Create thread id failed"); + } + + if (mType == Notes.TYPE_NOTE) { + for (SqlData sqlData : mDataList) { + sqlData.commit(mId, false, -1); + } + } + } else { + if (mId <= 0 && mId != Notes.ID_ROOT_FOLDER && mId != Notes.ID_CALL_RECORD_FOLDER) { + Log.e(TAG, "No such note"); + throw new IllegalStateException("Try to update note with invalid id"); + } + if (mDiffNoteValues.size() > 0) { + mVersion ++; + int result = 0; + if (!validateVersion) { + result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "(" + + NoteColumns.ID + "=?)", new String[] { + String.valueOf(mId) + }); + } else { + result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "(" + + NoteColumns.ID + "=?) AND (" + NoteColumns.VERSION + "<=?)", + new String[] { + String.valueOf(mId), String.valueOf(mVersion) + }); + } + if (result == 0) { + Log.w(TAG, "there is no update. maybe user updates note when syncing"); + } + } + + if (mType == Notes.TYPE_NOTE) { + for (SqlData sqlData : mDataList) { + sqlData.commit(mId, validateVersion, mVersion); + } + } + } + + // refresh local info + loadFromCursor(mId); + if (mType == Notes.TYPE_NOTE) + loadDataContent(); + + mDiffNoteValues.clear(); + mIsCreate = false; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Task.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Task.java new file mode 100644 index 0000000..6a19454 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/Task.java @@ -0,0 +1,351 @@ +/* + * 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.database.Cursor; +import android.text.TextUtils; +import android.util.Log; + +import net.micode.notes.data.Notes; +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.gtask.exception.ActionFailureException; +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + + +public class Task extends Node { + private static final String TAG = Task.class.getSimpleName(); + + private boolean mCompleted; + + private String mNotes; + + private JSONObject mMetaInfo; + + private Task mPriorSibling; + + private TaskList mParent; + + public Task() { + super(); + mCompleted = false; + mNotes = null; + mPriorSibling = null; + mParent = null; + mMetaInfo = null; + } + + public JSONObject getCreateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // index + js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this)); + + // entity_delta + JSONObject entity = new JSONObject(); + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); + 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); + + // parent_id + js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid()); + + // dest_parent_type + js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE, + GTaskStringUtils.GTASK_JSON_TYPE_GROUP); + + // list_id + js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid()); + + // prior_sibling_id + if (mPriorSibling != null) { + js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid()); + } + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate task-create jsonobject"); + } + + return js; + } + + public JSONObject getUpdateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // id + js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); + + // entity_delta + 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) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate task-update jsonobject"); + } + + return js; + } + + public void setContentByRemoteJSON(JSONObject js) { + if (js != null) { + try { + // id + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { + setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); + } + + // last_modified + if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { + setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); + } + + // name + if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { + setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); + } + + // notes + if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) { + setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES)); + } + + // deleted + if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) { + setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED)); + } + + // completed + if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) { + setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED)); + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to get task content from jsonobject"); + } + } + } + + 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)) { + setName(data.getString(DataColumns.CONTENT)); + break; + } + } + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + } + + public JSONObject getLocalJSONFromContent() { + String name = getName(); + try { + if (mMetaInfo == null) { + // new task created from web + if (name == null) { + Log.w(TAG, "the note seems to be an empty one"); + return null; + } + + JSONObject js = new JSONObject(); + 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; + } else { + // synced task + 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) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return null; + } + } + + public void setMetaInfo(MetaData metaData) { + if (metaData != null && metaData.getNotes() != null) { + try { + mMetaInfo = new JSONObject(metaData.getNotes()); + } catch (JSONException e) { + Log.w(TAG, e.toString()); + mMetaInfo = 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)) { + Log.w(TAG, "remote note id seems to be deleted"); + return SYNC_ACTION_UPDATE_LOCAL; + } + + // validate the note id now + 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) { + // there is no local update + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { + // no update both side + return SYNC_ACTION_NONE; + } else { + // apply remote to local + return SYNC_ACTION_UPDATE_LOCAL; + } + } else { + // validate 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()) { + // local modification only + 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; + } + +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/TaskList.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/TaskList.java new file mode 100644 index 0000000..4ea21c5 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/data/TaskList.java @@ -0,0 +1,343 @@ +/* + * 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.database.Cursor; +import android.util.Log; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + + +public class TaskList extends Node { + private static final String TAG = TaskList.class.getSimpleName(); + + private int mIndex; + + private ArrayList mChildren; + + public TaskList() { + super(); + mChildren = new ArrayList(); + mIndex = 1; + } + + public JSONObject getCreateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // index + js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex); + + // entity_delta + JSONObject entity = new JSONObject(); + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); + entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, + GTaskStringUtils.GTASK_JSON_TYPE_GROUP); + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate tasklist-create jsonobject"); + } + + return js; + } + + public JSONObject getUpdateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // id + js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); + + // entity_delta + JSONObject entity = new JSONObject(); + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate tasklist-update jsonobject"); + } + + return js; + } + + public void setContentByRemoteJSON(JSONObject js) { + if (js != null) { + try { + // id + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { + setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); + } + + // last_modified + if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { + setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); + } + + // name + if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { + setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); + } + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to get tasklist content from jsonobject"); + } + } + } + + public void setContentByLocalJSON(JSONObject js) { + if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { + Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); + } + + try { + JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + + if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { + String name = folder.getString(NoteColumns.SNIPPET); + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name); + } else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { + if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER) + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT); + else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER) + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_CALL_NOTE); + else + Log.e(TAG, "invalid system folder"); + } else { + Log.e(TAG, "error type"); + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + } + + public JSONObject getLocalJSONFromContent() { + try { + JSONObject js = new JSONObject(); + JSONObject folder = new JSONObject(); + + String folderName = getName(); + if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX)) + folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(), + folderName.length()); + folder.put(NoteColumns.SNIPPET, folderName); + if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT) + || folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE)) + folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + else + folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + + js.put(GTaskStringUtils.META_HEAD_NOTE, folder); + + return js; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return null; + } + } + + public int getSyncAction(Cursor c) { + try { + if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { + // there is no local update + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { + // no update both side + return SYNC_ACTION_NONE; + } else { + // apply remote to local + return SYNC_ACTION_UPDATE_LOCAL; + } + } else { + // validate 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()) { + // local modification only + return SYNC_ACTION_UPDATE_REMOTE; + } else { + // for folder conflicts, just apply local modification + return SYNC_ACTION_UPDATE_REMOTE; + } + } + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + + return SYNC_ACTION_ERROR; + } + + public int getChildTaskCount() { + return mChildren.size(); + } + + public boolean addChildTask(Task task) { + boolean ret = false; + if (task != null && !mChildren.contains(task)) { + ret = mChildren.add(task); + if (ret) { + // need to set prior sibling and parent + task.setPriorSibling(mChildren.isEmpty() ? null : mChildren + .get(mChildren.size() - 1)); + task.setParent(this); + } + } + return ret; + } + + public boolean addChildTask(Task task, int index) { + if (index < 0 || index > mChildren.size()) { + Log.e(TAG, "add child task: invalid index"); + return false; + } + + int pos = mChildren.indexOf(task); + if (task != null && pos == -1) { + mChildren.add(index, task); + + // update the task list + Task preTask = null; + Task afterTask = null; + if (index != 0) + preTask = mChildren.get(index - 1); + if (index != mChildren.size() - 1) + afterTask = mChildren.get(index + 1); + + task.setPriorSibling(preTask); + if (afterTask != null) + afterTask.setPriorSibling(task); + } + + return true; + } + + public boolean removeChildTask(Task task) { + boolean ret = false; + int index = mChildren.indexOf(task); + if (index != -1) { + ret = mChildren.remove(task); + + if (ret) { + // reset prior sibling and parent + task.setPriorSibling(null); + task.setParent(null); + + // update the task list + if (index != mChildren.size()) { + mChildren.get(index).setPriorSibling( + index == 0 ? null : mChildren.get(index - 1)); + } + } + } + return ret; + } + + public boolean moveChildTask(Task task, int index) { + + if (index < 0 || index >= mChildren.size()) { + Log.e(TAG, "move child task: invalid index"); + return false; + } + + int pos = mChildren.indexOf(task); + if (pos == -1) { + Log.e(TAG, "move child task: the task should in the list"); + return false; + } + + if (pos == index) + return true; + return (removeChildTask(task) && addChildTask(task, index)); + } + + public Task findChildTaskByGid(String gid) { + for (int i = 0; i < mChildren.size(); i++) { + Task t = mChildren.get(i); + if (t.getGid().equals(gid)) { + return t; + } + } + return null; + } + + public int getChildTaskIndex(Task task) { + return mChildren.indexOf(task); + } + + public Task getChildTaskByIndex(int index) { + if (index < 0 || index >= mChildren.size()) { + Log.e(TAG, "getTaskByIndex: invalid index"); + return null; + } + return mChildren.get(index); + } + + public Task getChilTaskByGid(String gid) { + for (Task task : mChildren) { + if (task.getGid().equals(gid)) + return task; + } + return null; + } + + public ArrayList getChildTaskList() { + return this.mChildren; + } + + public void setIndex(int index) { + this.mIndex = index; + } + + public int getIndex() { + return this.mIndex; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/ActionFailureException.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/ActionFailureException.java new file mode 100644 index 0000000..15504be --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/ActionFailureException.java @@ -0,0 +1,33 @@ +/* + * 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.exception; + +public class ActionFailureException extends RuntimeException { + private static final long serialVersionUID = 4425249765923293627L; + + public ActionFailureException() { + super(); + } + + public ActionFailureException(String paramString) { + super(paramString); + } + + public ActionFailureException(String paramString, Throwable paramThrowable) { + super(paramString, paramThrowable); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/NetworkFailureException.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/NetworkFailureException.java new file mode 100644 index 0000000..b08cfb1 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/exception/NetworkFailureException.java @@ -0,0 +1,33 @@ +/* + * 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.exception; + +public class NetworkFailureException extends Exception { + private static final long serialVersionUID = 2107610287180234136L; + + public NetworkFailureException() { + super(); + } + + public NetworkFailureException(String paramString) { + super(paramString); + } + + public NetworkFailureException(String paramString, Throwable paramThrowable) { + super(paramString, paramThrowable); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskASyncTask.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskASyncTask.java new file mode 100644 index 0000000..b3b61e7 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskASyncTask.java @@ -0,0 +1,123 @@ + +/* + * 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.remote; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; + +import net.micode.notes.R; +import net.micode.notes.ui.NotesListActivity; +import net.micode.notes.ui.NotesPreferenceActivity; + + +public class GTaskASyncTask extends AsyncTask { + + private static int GTASK_SYNC_NOTIFICATION_ID = 5234235; + + public interface OnCompleteListener { + void onComplete(); + } + + private Context mContext; + + private NotificationManager mNotifiManager; + + private GTaskManager mTaskManager; + + private OnCompleteListener mOnCompleteListener; + + public GTaskASyncTask(Context context, OnCompleteListener listener) { + mContext = context; + mOnCompleteListener = listener; + mNotifiManager = (NotificationManager) mContext + .getSystemService(Context.NOTIFICATION_SERVICE); + mTaskManager = GTaskManager.getInstance(); + } + + public void cancelSync() { + mTaskManager.cancelSync(); + } + + public void publishProgess(String message) { + publishProgress(new String[] { + message + }); + } + + private void showNotification(int tickerId, String content) { + Notification notification = new Notification(R.drawable.notification, mContext + .getString(tickerId), System.currentTimeMillis()); + notification.defaults = Notification.DEFAULT_LIGHTS; + notification.flags = Notification.FLAG_AUTO_CANCEL; + PendingIntent pendingIntent; + if (tickerId != R.string.ticker_success) { + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + NotesPreferenceActivity.class), 0); + + } else { + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + NotesListActivity.class), 0); + } + notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content, + pendingIntent); + mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification); + } + + @Override + protected Integer doInBackground(Void... unused) { + publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity + .getSyncAccountName(mContext))); + return mTaskManager.sync(mContext, this); + } + + @Override + protected void onProgressUpdate(String... progress) { + showNotification(R.string.ticker_syncing, progress[0]); + if (mContext instanceof GTaskSyncService) { + ((GTaskSyncService) mContext).sendBroadcast(progress[0]); + } + } + + @Override + protected void onPostExecute(Integer result) { + if (result == GTaskManager.STATE_SUCCESS) { + showNotification(R.string.ticker_success, mContext.getString( + R.string.success_sync_account, mTaskManager.getSyncAccount())); + NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis()); + } else if (result == GTaskManager.STATE_NETWORK_ERROR) { + showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_network)); + } else if (result == GTaskManager.STATE_INTERNAL_ERROR) { + showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_internal)); + } else if (result == GTaskManager.STATE_SYNC_CANCELLED) { + showNotification(R.string.ticker_cancel, mContext + .getString(R.string.error_sync_cancelled)); + } + if (mOnCompleteListener != null) { + new Thread(new Runnable() { + + public void run() { + mOnCompleteListener.onComplete(); + } + }).start(); + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskClient.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskClient.java new file mode 100644 index 0000000..c67dfdf --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskClient.java @@ -0,0 +1,585 @@ +/* + * 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.remote; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerFuture; +import android.app.Activity; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; + +import net.micode.notes.gtask.data.Node; +import net.micode.notes.gtask.data.Task; +import net.micode.notes.gtask.data.TaskList; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.gtask.exception.NetworkFailureException; +import net.micode.notes.tool.GTaskStringUtils; +import net.micode.notes.ui.NotesPreferenceActivity; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.cookie.Cookie; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.LinkedList; +import java.util.List; +import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + + +public class GTaskClient { + private static final String TAG = GTaskClient.class.getSimpleName(); + + private static final String GTASK_URL = "https://mail.google.com/tasks/"; + + private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig"; + + private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig"; + + private static GTaskClient mInstance = null; + + private DefaultHttpClient mHttpClient; + + private String mGetUrl; + + private String mPostUrl; + + private long mClientVersion; + + private boolean mLoggedin; + + private long mLastLoginTime; + + private int mActionId; + + private Account mAccount; + + private JSONArray mUpdateArray; + + private GTaskClient() { + mHttpClient = null; + mGetUrl = GTASK_GET_URL; + mPostUrl = GTASK_POST_URL; + mClientVersion = -1; + mLoggedin = false; + mLastLoginTime = 0; + mActionId = 1; + mAccount = null; + mUpdateArray = null; + } + + public static synchronized GTaskClient getInstance() { + if (mInstance == null) { + mInstance = new GTaskClient(); + } + return mInstance; + } + + public boolean login(Activity activity) { + // we suppose that the cookie would expire after 5 minutes + // then we need to re-login + final long interval = 1000 * 60 * 5; + if (mLastLoginTime + interval < System.currentTimeMillis()) { + mLoggedin = false; + } + + // need to re-login after account switch + if (mLoggedin + && !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity + .getSyncAccountName(activity))) { + mLoggedin = false; + } + + if (mLoggedin) { + Log.d(TAG, "already logged in"); + return true; + } + + mLastLoginTime = System.currentTimeMillis(); + String authToken = loginGoogleAccount(activity, false); + if (authToken == null) { + Log.e(TAG, "login google account failed"); + return false; + } + + // login with custom domain if necessary + if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() + .endsWith("googlemail.com"))) { + StringBuilder url = new StringBuilder(GTASK_URL).append("a/"); + int index = mAccount.name.indexOf('@') + 1; + String suffix = mAccount.name.substring(index); + url.append(suffix + "/"); + mGetUrl = url.toString() + "ig"; + mPostUrl = url.toString() + "r/ig"; + + if (tryToLoginGtask(activity, authToken)) { + mLoggedin = true; + } + } + + // try to login with google official url + if (!mLoggedin) { + mGetUrl = GTASK_GET_URL; + mPostUrl = GTASK_POST_URL; + if (!tryToLoginGtask(activity, authToken)) { + return false; + } + } + + mLoggedin = true; + return true; + } + + private String loginGoogleAccount(Activity activity, boolean invalidateToken) { + String authToken; + AccountManager accountManager = AccountManager.get(activity); + Account[] accounts = accountManager.getAccountsByType("com.google"); + + if (accounts.length == 0) { + Log.e(TAG, "there is no available google account"); + return null; + } + + String accountName = NotesPreferenceActivity.getSyncAccountName(activity); + Account account = null; + for (Account a : accounts) { + if (a.name.equals(accountName)) { + account = a; + break; + } + } + if (account != null) { + mAccount = account; + } else { + Log.e(TAG, "unable to get an account with the same name in the settings"); + return null; + } + + // get the token now + AccountManagerFuture accountManagerFuture = accountManager.getAuthToken(account, + "goanna_mobile", null, activity, null, null); + try { + Bundle authTokenBundle = accountManagerFuture.getResult(); + authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN); + if (invalidateToken) { + accountManager.invalidateAuthToken("com.google", authToken); + loginGoogleAccount(activity, false); + } + } catch (Exception e) { + Log.e(TAG, "get auth token failed"); + authToken = null; + } + + return authToken; + } + + private boolean tryToLoginGtask(Activity activity, String authToken) { + if (!loginGtask(authToken)) { + // maybe the auth token is out of date, now let's invalidate the + // token and try again + authToken = loginGoogleAccount(activity, true); + if (authToken == null) { + Log.e(TAG, "login google account failed"); + return false; + } + + if (!loginGtask(authToken)) { + Log.e(TAG, "login gtask failed"); + return false; + } + } + return true; + } + + private boolean loginGtask(String authToken) { + int timeoutConnection = 10000; + int timeoutSocket = 15000; + HttpParams httpParameters = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); + HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); + mHttpClient = new DefaultHttpClient(httpParameters); + BasicCookieStore localBasicCookieStore = new BasicCookieStore(); + mHttpClient.setCookieStore(localBasicCookieStore); + HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); + + // login gtask + try { + String loginUrl = mGetUrl + "?auth=" + authToken; + HttpGet httpGet = new HttpGet(loginUrl); + HttpResponse response = null; + response = mHttpClient.execute(httpGet); + + // get the cookie now + List cookies = mHttpClient.getCookieStore().getCookies(); + boolean hasAuthCookie = false; + for (Cookie cookie : cookies) { + if (cookie.getName().contains("GTL")) { + hasAuthCookie = true; + } + } + if (!hasAuthCookie) { + Log.w(TAG, "it seems that there is no auth cookie"); + } + + // get the client version + String resString = getResponseContent(response.getEntity()); + String jsBegin = "_setup("; + String jsEnd = ")}"; + int begin = resString.indexOf(jsBegin); + int end = resString.lastIndexOf(jsEnd); + String jsString = null; + if (begin != -1 && end != -1 && begin < end) { + jsString = resString.substring(begin + jsBegin.length(), end); + } + JSONObject js = new JSONObject(jsString); + mClientVersion = js.getLong("v"); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return false; + } catch (Exception e) { + // simply catch all exceptions + Log.e(TAG, "httpget gtask_url failed"); + return false; + } + + return true; + } + + private int getActionId() { + return mActionId++; + } + + private HttpPost createHttpPost() { + HttpPost httpPost = new HttpPost(mPostUrl); + httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); + httpPost.setHeader("AT", "1"); + return httpPost; + } + + private String getResponseContent(HttpEntity entity) throws IOException { + String contentEncoding = null; + if (entity.getContentEncoding() != null) { + contentEncoding = entity.getContentEncoding().getValue(); + Log.d(TAG, "encoding: " + contentEncoding); + } + + InputStream input = entity.getContent(); + if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { + input = new GZIPInputStream(entity.getContent()); + } else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) { + Inflater inflater = new Inflater(true); + input = new InflaterInputStream(entity.getContent(), inflater); + } + + try { + InputStreamReader isr = new InputStreamReader(input); + BufferedReader br = new BufferedReader(isr); + StringBuilder sb = new StringBuilder(); + + while (true) { + String buff = br.readLine(); + if (buff == null) { + return sb.toString(); + } + sb = sb.append(buff); + } + } finally { + input.close(); + } + } + + private JSONObject postRequest(JSONObject js) throws NetworkFailureException { + if (!mLoggedin) { + Log.e(TAG, "please login first"); + throw new ActionFailureException("not logged in"); + } + + HttpPost httpPost = createHttpPost(); + try { + LinkedList list = new LinkedList(); + list.add(new BasicNameValuePair("r", js.toString())); + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8"); + httpPost.setEntity(entity); + + // execute the post + HttpResponse response = mHttpClient.execute(httpPost); + String jsString = getResponseContent(response.getEntity()); + return new JSONObject(jsString); + + } catch (ClientProtocolException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("postRequest failed"); + } catch (IOException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("postRequest failed"); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("unable to convert response content to jsonobject"); + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("error occurs when posting request"); + } + } + + public void createTask(Task task) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + + // action_list + actionList.put(task.getCreateAction(getActionId())); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + // post + JSONObject jsResponse = postRequest(jsPost); + JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( + GTaskStringUtils.GTASK_JSON_RESULTS).get(0); + task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("create task: handing jsonobject failed"); + } + } + + public void createTaskList(TaskList tasklist) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + + // action_list + actionList.put(tasklist.getCreateAction(getActionId())); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + // post + JSONObject jsResponse = postRequest(jsPost); + JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( + GTaskStringUtils.GTASK_JSON_RESULTS).get(0); + tasklist.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("create tasklist: handing jsonobject failed"); + } + } + + public void commitUpdate() throws NetworkFailureException { + if (mUpdateArray != null) { + try { + JSONObject jsPost = new JSONObject(); + + // action_list + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + postRequest(jsPost); + mUpdateArray = null; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("commit update: handing jsonobject failed"); + } + } + } + + public void addUpdateNode(Node node) throws NetworkFailureException { + if (node != null) { + // too many update items may result in an error + // set max to 10 items + if (mUpdateArray != null && mUpdateArray.length() > 10) { + commitUpdate(); + } + + if (mUpdateArray == null) + mUpdateArray = new JSONArray(); + mUpdateArray.put(node.getUpdateAction(getActionId())); + } + } + + public void moveTask(Task task, TaskList preParent, TaskList curParent) + throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + JSONObject action = new JSONObject(); + + // action_list + action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE); + action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); + action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid()); + if (preParent == curParent && task.getPriorSibling() != null) { + // put prioring_sibing_id only if moving within the tasklist and + // it is not the first one + action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling()); + } + action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid()); + action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid()); + if (preParent != curParent) { + // put the dest_list only if moving between tasklists + action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid()); + } + actionList.put(action); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + postRequest(jsPost); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("move task: handing jsonobject failed"); + } + } + + public void deleteNode(Node node) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + + // action_list + node.setDeleted(true); + actionList.put(node.getUpdateAction(getActionId())); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + postRequest(jsPost); + mUpdateArray = null; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("delete node: handing jsonobject failed"); + } + } + + public JSONArray getTaskLists() throws NetworkFailureException { + if (!mLoggedin) { + Log.e(TAG, "please login first"); + throw new ActionFailureException("not logged in"); + } + + try { + HttpGet httpGet = new HttpGet(mGetUrl); + HttpResponse response = null; + response = mHttpClient.execute(httpGet); + + // get the task list + String resString = getResponseContent(response.getEntity()); + String jsBegin = "_setup("; + String jsEnd = ")}"; + int begin = resString.indexOf(jsBegin); + int end = resString.lastIndexOf(jsEnd); + String jsString = null; + if (begin != -1 && end != -1 && begin < end) { + jsString = resString.substring(begin + jsBegin.length(), end); + } + JSONObject js = new JSONObject(jsString); + return js.getJSONObject("t").getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS); + } catch (ClientProtocolException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("gettasklists: httpget failed"); + } catch (IOException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("gettasklists: httpget failed"); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("get task lists: handing jasonobject failed"); + } + } + + public JSONArray getTaskList(String listGid) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + JSONObject action = new JSONObject(); + + // action_list + action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL); + action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); + action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid); + action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, false); + actionList.put(action); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + JSONObject jsResponse = postRequest(jsPost); + return jsResponse.getJSONArray(GTaskStringUtils.GTASK_JSON_TASKS); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("get task list: handing jsonobject failed"); + } + } + + public Account getSyncAccount() { + return mAccount; + } + + public void resetUpdateArray() { + mUpdateArray = null; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskManager.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskManager.java new file mode 100644 index 0000000..d2b4082 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskManager.java @@ -0,0 +1,800 @@ +/* + * 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.remote; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.util.Log; + +import net.micode.notes.R; +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.data.MetaData; +import net.micode.notes.gtask.data.Node; +import net.micode.notes.gtask.data.SqlNote; +import net.micode.notes.gtask.data.Task; +import net.micode.notes.gtask.data.TaskList; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.gtask.exception.NetworkFailureException; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + + +public class GTaskManager { + private static final String TAG = GTaskManager.class.getSimpleName(); + + public static final int STATE_SUCCESS = 0; + + public static final int STATE_NETWORK_ERROR = 1; + + public static final int STATE_INTERNAL_ERROR = 2; + + public static final int STATE_SYNC_IN_PROGRESS = 3; + + public static final int STATE_SYNC_CANCELLED = 4; + + private static GTaskManager mInstance = null; + + private Activity mActivity; + + private Context mContext; + + private ContentResolver mContentResolver; + + private boolean mSyncing; + + private boolean mCancelled; + + private HashMap mGTaskListHashMap; + + private HashMap mGTaskHashMap; + + private HashMap mMetaHashMap; + + private TaskList mMetaList; + + private HashSet mLocalDeleteIdMap; + + private HashMap mGidToNid; + + private HashMap mNidToGid; + + private GTaskManager() { + mSyncing = false; + mCancelled = false; + mGTaskListHashMap = new HashMap(); + mGTaskHashMap = new HashMap(); + mMetaHashMap = new HashMap(); + mMetaList = null; + mLocalDeleteIdMap = new HashSet(); + mGidToNid = new HashMap(); + mNidToGid = new HashMap(); + } + + public static synchronized GTaskManager getInstance() { + if (mInstance == null) { + mInstance = new GTaskManager(); + } + return mInstance; + } + + public synchronized void setActivityContext(Activity activity) { + // used for getting authtoken + mActivity = activity; + } + + public int sync(Context context, GTaskASyncTask asyncTask) { + if (mSyncing) { + Log.d(TAG, "Sync is in progress"); + return STATE_SYNC_IN_PROGRESS; + } + mContext = context; + mContentResolver = mContext.getContentResolver(); + mSyncing = true; + mCancelled = false; + mGTaskListHashMap.clear(); + mGTaskHashMap.clear(); + mMetaHashMap.clear(); + mLocalDeleteIdMap.clear(); + mGidToNid.clear(); + mNidToGid.clear(); + + try { + GTaskClient client = GTaskClient.getInstance(); + client.resetUpdateArray(); + + // login google task + if (!mCancelled) { + if (!client.login(mActivity)) { + throw new NetworkFailureException("login google task failed"); + } + } + + // get the task list from google + asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list)); + initGTaskList(); + + // do content sync work + asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing)); + syncContent(); + } catch (NetworkFailureException e) { + Log.e(TAG, e.toString()); + return STATE_NETWORK_ERROR; + } catch (ActionFailureException e) { + Log.e(TAG, e.toString()); + return STATE_INTERNAL_ERROR; + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return STATE_INTERNAL_ERROR; + } finally { + mGTaskListHashMap.clear(); + mGTaskHashMap.clear(); + mMetaHashMap.clear(); + mLocalDeleteIdMap.clear(); + mGidToNid.clear(); + mNidToGid.clear(); + mSyncing = false; + } + + return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS; + } + + private void initGTaskList() throws NetworkFailureException { + if (mCancelled) + return; + GTaskClient client = GTaskClient.getInstance(); + try { + JSONArray jsTaskLists = client.getTaskLists(); + + // init meta list first + mMetaList = null; + for (int i = 0; i < jsTaskLists.length(); i++) { + JSONObject object = jsTaskLists.getJSONObject(i); + String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); + String name = object.getString(GTaskStringUtils.GTASK_JSON_NAME); + + if (name + .equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_META)) { + mMetaList = new TaskList(); + mMetaList.setContentByRemoteJSON(object); + + // load meta data + JSONArray jsMetas = client.getTaskList(gid); + for (int j = 0; j < jsMetas.length(); j++) { + object = (JSONObject) jsMetas.getJSONObject(j); + MetaData metaData = new MetaData(); + metaData.setContentByRemoteJSON(object); + if (metaData.isWorthSaving()) { + mMetaList.addChildTask(metaData); + if (metaData.getGid() != null) { + mMetaHashMap.put(metaData.getRelatedGid(), metaData); + } + } + } + } + } + + // create meta list if not existed + if (mMetaList == null) { + mMetaList = new TaskList(); + mMetaList.setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_META); + GTaskClient.getInstance().createTaskList(mMetaList); + } + + // init task list + for (int i = 0; i < jsTaskLists.length(); i++) { + JSONObject object = jsTaskLists.getJSONObject(i); + String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); + String name = object.getString(GTaskStringUtils.GTASK_JSON_NAME); + + if (name.startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX) + && !name.equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_META)) { + TaskList tasklist = new TaskList(); + tasklist.setContentByRemoteJSON(object); + mGTaskListHashMap.put(gid, tasklist); + mGTaskHashMap.put(gid, tasklist); + + // load tasks + JSONArray jsTasks = client.getTaskList(gid); + for (int j = 0; j < jsTasks.length(); j++) { + object = (JSONObject) jsTasks.getJSONObject(j); + gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); + Task task = new Task(); + task.setContentByRemoteJSON(object); + if (task.isWorthSaving()) { + task.setMetaInfo(mMetaHashMap.get(gid)); + tasklist.addChildTask(task); + mGTaskHashMap.put(gid, task); + } + } + } + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("initGTaskList: handing JSONObject failed"); + } + } + + private void syncContent() throws NetworkFailureException { + int syncType; + Cursor c = null; + String gid; + Node node; + + mLocalDeleteIdMap.clear(); + + if (mCancelled) { + return; + } + + // for local deleted note + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type<>? AND parent_id=?)", new String[] { + String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER) + }, null); + if (c != null) { + while (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + doContentSync(Node.SYNC_ACTION_DEL_REMOTE, node, c); + } + + mLocalDeleteIdMap.add(c.getLong(SqlNote.ID_COLUMN)); + } + } else { + Log.w(TAG, "failed to query trash folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // sync folder first + syncFolder(); + + // for note existing in database + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type=? AND parent_id<>?)", new String[] { + String.valueOf(Notes.TYPE_NOTE), String.valueOf(Notes.ID_TRASH_FOLER) + }, NoteColumns.TYPE + " DESC"); + if (c != null) { + while (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, c.getLong(SqlNote.ID_COLUMN)); + mNidToGid.put(c.getLong(SqlNote.ID_COLUMN), gid); + syncType = node.getSyncAction(c); + } else { + if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { + // local add + syncType = Node.SYNC_ACTION_ADD_REMOTE; + } else { + // remote delete + syncType = Node.SYNC_ACTION_DEL_LOCAL; + } + } + doContentSync(syncType, node, c); + } + } else { + Log.w(TAG, "failed to query existing note in database"); + } + + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // go through remaining items + Iterator> iter = mGTaskHashMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + node = entry.getValue(); + doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); + } + + // mCancelled can be set by another thread, so we neet to check one by + // one + // clear local delete table + if (!mCancelled) { + if (!DataUtils.batchDeleteNotes(mContentResolver, mLocalDeleteIdMap)) { + throw new ActionFailureException("failed to batch-delete local deleted notes"); + } + } + + // refresh local sync id + if (!mCancelled) { + GTaskClient.getInstance().commitUpdate(); + refreshLocalSyncId(); + } + + } + + private void syncFolder() throws NetworkFailureException { + Cursor c = null; + String gid; + Node node; + int syncType; + + if (mCancelled) { + return; + } + + // for root folder + try { + c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, + Notes.ID_ROOT_FOLDER), SqlNote.PROJECTION_NOTE, null, null, null); + if (c != null) { + c.moveToNext(); + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, (long) Notes.ID_ROOT_FOLDER); + mNidToGid.put((long) Notes.ID_ROOT_FOLDER, gid); + // for system folder, only update remote name if necessary + if (!node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) + doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); + } else { + doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c); + } + } else { + Log.w(TAG, "failed to query root folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // for call-note folder + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)", + new String[] { + String.valueOf(Notes.ID_CALL_RECORD_FOLDER) + }, null); + if (c != null) { + if (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, (long) Notes.ID_CALL_RECORD_FOLDER); + mNidToGid.put((long) Notes.ID_CALL_RECORD_FOLDER, gid); + // for system folder, only update remote name if + // necessary + if (!node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_CALL_NOTE)) + doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); + } else { + doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c); + } + } + } else { + Log.w(TAG, "failed to query call note folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // for local existing folders + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type=? AND parent_id<>?)", new String[] { + String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER) + }, NoteColumns.TYPE + " DESC"); + if (c != null) { + while (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, c.getLong(SqlNote.ID_COLUMN)); + mNidToGid.put(c.getLong(SqlNote.ID_COLUMN), gid); + syncType = node.getSyncAction(c); + } else { + if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { + // local add + syncType = Node.SYNC_ACTION_ADD_REMOTE; + } else { + // remote delete + syncType = Node.SYNC_ACTION_DEL_LOCAL; + } + } + doContentSync(syncType, node, c); + } + } else { + Log.w(TAG, "failed to query existing folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // for remote add folders + Iterator> iter = mGTaskListHashMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + gid = entry.getKey(); + node = entry.getValue(); + if (mGTaskHashMap.containsKey(gid)) { + mGTaskHashMap.remove(gid); + doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); + } + } + + if (!mCancelled) + GTaskClient.getInstance().commitUpdate(); + } + + private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + MetaData meta; + switch (syncType) { + case Node.SYNC_ACTION_ADD_LOCAL: + addLocalNode(node); + break; + case Node.SYNC_ACTION_ADD_REMOTE: + addRemoteNode(node, c); + break; + case Node.SYNC_ACTION_DEL_LOCAL: + meta = mMetaHashMap.get(c.getString(SqlNote.GTASK_ID_COLUMN)); + if (meta != null) { + GTaskClient.getInstance().deleteNode(meta); + } + mLocalDeleteIdMap.add(c.getLong(SqlNote.ID_COLUMN)); + break; + case Node.SYNC_ACTION_DEL_REMOTE: + meta = mMetaHashMap.get(node.getGid()); + if (meta != null) { + GTaskClient.getInstance().deleteNode(meta); + } + GTaskClient.getInstance().deleteNode(node); + break; + case Node.SYNC_ACTION_UPDATE_LOCAL: + updateLocalNode(node, c); + break; + case Node.SYNC_ACTION_UPDATE_REMOTE: + updateRemoteNode(node, c); + break; + case Node.SYNC_ACTION_UPDATE_CONFLICT: + // merging both modifications maybe a good idea + // right now just use local update simply + updateRemoteNode(node, c); + break; + case Node.SYNC_ACTION_NONE: + break; + case Node.SYNC_ACTION_ERROR: + default: + throw new ActionFailureException("unkown sync action type"); + } + } + + private void addLocalNode(Node node) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote; + if (node instanceof TaskList) { + if (node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) { + sqlNote = new SqlNote(mContext, Notes.ID_ROOT_FOLDER); + } else if (node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) { + sqlNote = new SqlNote(mContext, Notes.ID_CALL_RECORD_FOLDER); + } else { + sqlNote = new SqlNote(mContext); + sqlNote.setContent(node.getLocalJSONFromContent()); + sqlNote.setParentId(Notes.ID_ROOT_FOLDER); + } + } else { + sqlNote = new SqlNote(mContext); + JSONObject js = node.getLocalJSONFromContent(); + try { + if (js.has(GTaskStringUtils.META_HEAD_NOTE)) { + JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + if (note.has(NoteColumns.ID)) { + long id = note.getLong(NoteColumns.ID); + if (DataUtils.existInNoteDatabase(mContentResolver, id)) { + // the id is not available, have to create a new one + note.remove(NoteColumns.ID); + } + } + } + + if (js.has(GTaskStringUtils.META_HEAD_DATA)) { + JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); + for (int i = 0; i < dataArray.length(); i++) { + JSONObject data = dataArray.getJSONObject(i); + if (data.has(DataColumns.ID)) { + long dataId = data.getLong(DataColumns.ID); + if (DataUtils.existInDataDatabase(mContentResolver, dataId)) { + // the data id is not available, have to create + // a new one + data.remove(DataColumns.ID); + } + } + } + + } + } catch (JSONException e) { + Log.w(TAG, e.toString()); + e.printStackTrace(); + } + sqlNote.setContent(js); + + Long parentId = mGidToNid.get(((Task) node).getParent().getGid()); + if (parentId == null) { + Log.e(TAG, "cannot find task's parent id locally"); + throw new ActionFailureException("cannot add local node"); + } + sqlNote.setParentId(parentId.longValue()); + } + + // create the local node + sqlNote.setGtaskId(node.getGid()); + sqlNote.commit(false); + + // update gid-nid mapping + mGidToNid.put(node.getGid(), sqlNote.getId()); + mNidToGid.put(sqlNote.getId(), node.getGid()); + + // update meta + updateRemoteMeta(node.getGid(), sqlNote); + } + + private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote; + // update the note locally + sqlNote = new SqlNote(mContext, c); + sqlNote.setContent(node.getLocalJSONFromContent()); + + Long parentId = (node instanceof Task) ? mGidToNid.get(((Task) node).getParent().getGid()) + : new Long(Notes.ID_ROOT_FOLDER); + if (parentId == null) { + Log.e(TAG, "cannot find task's parent id locally"); + throw new ActionFailureException("cannot update local node"); + } + sqlNote.setParentId(parentId.longValue()); + sqlNote.commit(true); + + // update meta info + updateRemoteMeta(node.getGid(), sqlNote); + } + + private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote = new SqlNote(mContext, c); + Node n; + + // update remotely + if (sqlNote.isNoteType()) { + Task task = new Task(); + task.setContentByLocalJSON(sqlNote.getContent()); + + String parentGid = mNidToGid.get(sqlNote.getParentId()); + if (parentGid == null) { + Log.e(TAG, "cannot find task's parent tasklist"); + throw new ActionFailureException("cannot add remote task"); + } + mGTaskListHashMap.get(parentGid).addChildTask(task); + + GTaskClient.getInstance().createTask(task); + n = (Node) task; + + // add meta + updateRemoteMeta(task.getGid(), sqlNote); + } else { + TaskList tasklist = null; + + // we need to skip folder if it has already existed + String folderName = GTaskStringUtils.MIUI_FOLDER_PREFFIX; + if (sqlNote.getId() == Notes.ID_ROOT_FOLDER) + folderName += GTaskStringUtils.FOLDER_DEFAULT; + else if (sqlNote.getId() == Notes.ID_CALL_RECORD_FOLDER) + folderName += GTaskStringUtils.FOLDER_CALL_NOTE; + else + folderName += sqlNote.getSnippet(); + + Iterator> iter = mGTaskListHashMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + String gid = entry.getKey(); + TaskList list = entry.getValue(); + + if (list.getName().equals(folderName)) { + tasklist = list; + if (mGTaskHashMap.containsKey(gid)) { + mGTaskHashMap.remove(gid); + } + break; + } + } + + // no match we can add now + if (tasklist == null) { + tasklist = new TaskList(); + tasklist.setContentByLocalJSON(sqlNote.getContent()); + GTaskClient.getInstance().createTaskList(tasklist); + mGTaskListHashMap.put(tasklist.getGid(), tasklist); + } + n = (Node) tasklist; + } + + // update local note + sqlNote.setGtaskId(n.getGid()); + sqlNote.commit(false); + sqlNote.resetLocalModified(); + sqlNote.commit(true); + + // gid-id mapping + mGidToNid.put(n.getGid(), sqlNote.getId()); + mNidToGid.put(sqlNote.getId(), n.getGid()); + } + + private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote = new SqlNote(mContext, c); + + // update remotely + node.setContentByLocalJSON(sqlNote.getContent()); + GTaskClient.getInstance().addUpdateNode(node); + + // update meta + updateRemoteMeta(node.getGid(), sqlNote); + + // move task if necessary + if (sqlNote.isNoteType()) { + Task task = (Task) node; + TaskList preParentList = task.getParent(); + + String curParentGid = mNidToGid.get(sqlNote.getParentId()); + if (curParentGid == null) { + Log.e(TAG, "cannot find task's parent tasklist"); + throw new ActionFailureException("cannot update remote task"); + } + TaskList curParentList = mGTaskListHashMap.get(curParentGid); + + if (preParentList != curParentList) { + preParentList.removeChildTask(task); + curParentList.addChildTask(task); + GTaskClient.getInstance().moveTask(task, preParentList, curParentList); + } + } + + // clear local modified flag + sqlNote.resetLocalModified(); + sqlNote.commit(true); + } + + private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException { + if (sqlNote != null && sqlNote.isNoteType()) { + MetaData metaData = mMetaHashMap.get(gid); + if (metaData != null) { + metaData.setMeta(gid, sqlNote.getContent()); + GTaskClient.getInstance().addUpdateNode(metaData); + } else { + metaData = new MetaData(); + metaData.setMeta(gid, sqlNote.getContent()); + mMetaList.addChildTask(metaData); + mMetaHashMap.put(gid, metaData); + GTaskClient.getInstance().createTask(metaData); + } + } + } + + private void refreshLocalSyncId() throws NetworkFailureException { + if (mCancelled) { + return; + } + + // get the latest gtask list + mGTaskHashMap.clear(); + mGTaskListHashMap.clear(); + mMetaHashMap.clear(); + initGTaskList(); + + Cursor c = null; + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type<>? AND parent_id<>?)", new String[] { + String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER) + }, NoteColumns.TYPE + " DESC"); + if (c != null) { + while (c.moveToNext()) { + String gid = c.getString(SqlNote.GTASK_ID_COLUMN); + Node node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + ContentValues values = new ContentValues(); + values.put(NoteColumns.SYNC_ID, node.getLastModified()); + mContentResolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, + c.getLong(SqlNote.ID_COLUMN)), values, null, null); + } else { + Log.e(TAG, "something is missed"); + throw new ActionFailureException( + "some local items don't have gid after sync"); + } + } + } else { + Log.w(TAG, "failed to query local note to refresh sync id"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + } + + public String getSyncAccount() { + return GTaskClient.getInstance().getSyncAccount().name; + } + + public void cancelSync() { + mCancelled = true; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskSyncService.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskSyncService.java new file mode 100644 index 0000000..cca36f7 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/gtask/remote/GTaskSyncService.java @@ -0,0 +1,128 @@ +/* + * 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.remote; + +import android.app.Activity; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; + +public class GTaskSyncService extends Service { + public final static String ACTION_STRING_NAME = "sync_action_type"; + + public final static int ACTION_START_SYNC = 0; + + public final static int ACTION_CANCEL_SYNC = 1; + + public final static int ACTION_INVALID = 2; + + public final static String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.remote.gtask_sync_service"; + + public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "isSyncing"; + + public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg"; + + private static GTaskASyncTask mSyncTask = null; + + private static String mSyncProgress = ""; + + private void startSync() { + if (mSyncTask == null) { + mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() { + public void onComplete() { + mSyncTask = null; + sendBroadcast(""); + stopSelf(); + } + }); + sendBroadcast(""); + mSyncTask.execute(); + } + } + + private void cancelSync() { + if (mSyncTask != null) { + mSyncTask.cancelSync(); + } + } + + @Override + public void onCreate() { + mSyncTask = null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Bundle bundle = intent.getExtras(); + if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) { + switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) { + case ACTION_START_SYNC: + startSync(); + break; + case ACTION_CANCEL_SYNC: + cancelSync(); + break; + default: + break; + } + return START_STICKY; + } + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onLowMemory() { + if (mSyncTask != null) { + mSyncTask.cancelSync(); + } + } + + public IBinder onBind(Intent intent) { + return null; + } + + public void sendBroadcast(String msg) { + mSyncProgress = msg; + Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME); + intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null); + intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg); + sendBroadcast(intent); + } + + public static void startSync(Activity activity) { + GTaskManager.getInstance().setActivityContext(activity); + Intent intent = new Intent(activity, GTaskSyncService.class); + intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC); + activity.startService(intent); + } + + public static void cancelSync(Context context) { + Intent intent = new Intent(context, GTaskSyncService.class); + intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC); + context.startService(intent); + } + + public static boolean isSyncing() { + return mSyncTask != null; + } + + public static String getProgressString() { + return mSyncProgress; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/Note.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/Note.java new file mode 100644 index 0000000..6706cf6 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/Note.java @@ -0,0 +1,253 @@ +/* + * 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; +import android.content.ContentValues; +import android.content.Context; +import android.content.OperationApplicationException; +import android.net.Uri; +import android.os.RemoteException; +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.NoteColumns; +import net.micode.notes.data.Notes.TextNote; + +import java.util.ArrayList; + + +public class Note { + private ContentValues mNoteDiffValues; + private NoteData mNoteData; + 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 + 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) { + 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) { + mNoteData.setTextDataId(id); + } + + public long getTextDataId() { + return mNoteData.mTextDataId; + } + + public void setCallDataId(long 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; + + private ContentValues mTextDataValues; + + private long mCallDataId; + + private ContentValues mCallDataValues; + + private static final String TAG = "NoteData"; + + public NoteData() { + mTextDataValues = new ContentValues(); + mCallDataValues = new ContentValues(); + mTextDataId = 0; + mCallDataId = 0; + } + + boolean isLocalModified() { + return mTextDataValues.size() > 0 || mCallDataValues.size() > 0; + } + + void setTextDataId(long id) { + if(id <= 0) { + throw new IllegalArgumentException("Text data id should larger than 0"); + } + mTextDataId = id; + } + + void setCallDataId(long 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) { + /** + * 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) { + mTextDataValues.put(DataColumns.NOTE_ID, noteId); + if (mTextDataId == 0) { + 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) { + 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 { + 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/src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/WorkingNote.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/WorkingNote.java new file mode 100644 index 0000000..be081e4 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/model/WorkingNote.java @@ -0,0 +1,368 @@ +/* + * 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; + + +public class 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[] { + 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 + }; + + 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) { + mContext = context; + mAlertDate = 0; + mModifiedDate = System.currentTimeMillis(); + mFolderId = folderId; + mNote = new Note(); + mNoteId = 0; + mIsDeleted = false; + mMode = 0; + mWidgetType = Notes.TYPE_WIDGET_INVALIDE; + } + + // 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() { + 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() { + 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() { + return (mAlertDate > 0 ? true : false); + } + + public String getContent() { + return mContent; + } + + public long getAlertDate() { + return mAlertDate; + } + + public long getModifiedDate() { + return mModifiedDate; + } + + public int getBgColorResId() { + return NoteBgResources.getNoteBgResource(mBgColorId); + } + + public int getBgColorId() { + return mBgColorId; + } + + public int getTitleBgResId() { + return NoteBgResources.getNoteTitleBgResource(mBgColorId); + } + + public int getCheckListMode() { + return mMode; + } + + public long getNoteId() { + return mNoteId; + } + + public long getFolderId() { + return mFolderId; + } + + public int getWidgetId() { + 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/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/BackupUtils.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/BackupUtils.java new file mode 100644 index 0000000..39f6ec4 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/BackupUtils.java @@ -0,0 +1,344 @@ +/* + * 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.tool; + +import android.content.Context; +import android.database.Cursor; +import android.os.Environment; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.util.Log; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.DataConstants; +import net.micode.notes.data.Notes.NoteColumns; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; + + +public class BackupUtils { + private static final String TAG = "BackupUtils"; + // Singleton stuff + private static BackupUtils sInstance; + + public static synchronized BackupUtils getInstance(Context context) { + if (sInstance == null) { + sInstance = new BackupUtils(context); + } + return sInstance; + } + + /** + * Following states are signs to represents backup or restore + * status + */ + // Currently, the sdcard is not mounted + public static final int STATE_SD_CARD_UNMOUONTED = 0; + // The backup file not exist + public static final int STATE_BACKUP_FILE_NOT_EXIST = 1; + // The data is not well formated, may be changed by other programs + public static final int STATE_DATA_DESTROIED = 2; + // Some run-time exception which causes restore or backup fails + public static final int STATE_SYSTEM_ERROR = 3; + // Backup or restore success + public static final int STATE_SUCCESS = 4; + + private TextExport mTextExport; + + private BackupUtils(Context context) { + mTextExport = new TextExport(context); + } + + private static boolean externalStorageAvailable() { + return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); + } + + public int exportToText() { + return mTextExport.exportToText(); + } + + public String getExportedTextFileName() { + return mTextExport.mFileName; + } + + public String getExportedTextFileDir() { + return mTextExport.mFileDirectory; + } + + private static class TextExport { + private static final String[] NOTE_PROJECTION = { + NoteColumns.ID, + NoteColumns.MODIFIED_DATE, + NoteColumns.SNIPPET, + NoteColumns.TYPE + }; + + private static final int NOTE_COLUMN_ID = 0; + + private static final int NOTE_COLUMN_MODIFIED_DATE = 1; + + private static final int NOTE_COLUMN_SNIPPET = 2; + + private static final String[] DATA_PROJECTION = { + DataColumns.CONTENT, + DataColumns.MIME_TYPE, + DataColumns.DATA1, + DataColumns.DATA2, + DataColumns.DATA3, + DataColumns.DATA4, + }; + + private static final int DATA_COLUMN_CONTENT = 0; + + private static final int DATA_COLUMN_MIME_TYPE = 1; + + private static final int DATA_COLUMN_CALL_DATE = 2; + + private static final int DATA_COLUMN_PHONE_NUMBER = 4; + + private final String [] TEXT_FORMAT; + private static final int FORMAT_FOLDER_NAME = 0; + private static final int FORMAT_NOTE_DATE = 1; + private static final int FORMAT_NOTE_CONTENT = 2; + + private Context mContext; + private String mFileName; + private String mFileDirectory; + + public TextExport(Context context) { + TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note); + mContext = context; + mFileName = ""; + mFileDirectory = ""; + } + + private String getFormat(int id) { + return TEXT_FORMAT[id]; + } + + /** + * Export the folder identified by folder id to text + */ + private void exportFolderToText(String folderId, PrintStream ps) { + // Query notes belong to this folder + Cursor notesCursor = mContext.getContentResolver().query(Notes.CONTENT_NOTE_URI, + NOTE_PROJECTION, NoteColumns.PARENT_ID + "=?", new String[] { + folderId + }, null); + + if (notesCursor != null) { + if (notesCursor.moveToFirst()) { + do { + // Print note's last modified date + ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format( + mContext.getString(R.string.format_datetime_mdhm), + notesCursor.getLong(NOTE_COLUMN_MODIFIED_DATE)))); + // Query data belong to this note + String noteId = notesCursor.getString(NOTE_COLUMN_ID); + exportNoteToText(noteId, ps); + } while (notesCursor.moveToNext()); + } + notesCursor.close(); + } + } + + /** + * Export note identified by id to a print stream + */ + private void exportNoteToText(String noteId, PrintStream ps) { + Cursor dataCursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, + DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[] { + noteId + }, null); + + if (dataCursor != null) { + if (dataCursor.moveToFirst()) { + do { + String mimeType = dataCursor.getString(DATA_COLUMN_MIME_TYPE); + if (DataConstants.CALL_NOTE.equals(mimeType)) { + // Print phone number + String phoneNumber = dataCursor.getString(DATA_COLUMN_PHONE_NUMBER); + long callDate = dataCursor.getLong(DATA_COLUMN_CALL_DATE); + String location = dataCursor.getString(DATA_COLUMN_CONTENT); + + if (!TextUtils.isEmpty(phoneNumber)) { + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), + phoneNumber)); + } + // Print call date + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), DateFormat + .format(mContext.getString(R.string.format_datetime_mdhm), + callDate))); + // Print call attachment location + if (!TextUtils.isEmpty(location)) { + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), + location)); + } + } else if (DataConstants.NOTE.equals(mimeType)) { + String content = dataCursor.getString(DATA_COLUMN_CONTENT); + if (!TextUtils.isEmpty(content)) { + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), + content)); + } + } + } while (dataCursor.moveToNext()); + } + dataCursor.close(); + } + // print a line separator between note + try { + ps.write(new byte[] { + Character.LINE_SEPARATOR, Character.LETTER_NUMBER + }); + } catch (IOException e) { + Log.e(TAG, e.toString()); + } + } + + /** + * Note will be exported as text which is user readable + */ + public int exportToText() { + if (!externalStorageAvailable()) { + Log.d(TAG, "Media was not mounted"); + return STATE_SD_CARD_UNMOUONTED; + } + + PrintStream ps = getExportToTextPrintStream(); + if (ps == null) { + Log.e(TAG, "get print stream error"); + return STATE_SYSTEM_ERROR; + } + // First export folder and its notes + Cursor folderCursor = mContext.getContentResolver().query( + Notes.CONTENT_NOTE_URI, + NOTE_PROJECTION, + "(" + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + " AND " + + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + ") OR " + + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER, null, null); + + if (folderCursor != null) { + if (folderCursor.moveToFirst()) { + do { + // Print folder's name + String folderName = ""; + if(folderCursor.getLong(NOTE_COLUMN_ID) == Notes.ID_CALL_RECORD_FOLDER) { + folderName = mContext.getString(R.string.call_record_folder_name); + } else { + folderName = folderCursor.getString(NOTE_COLUMN_SNIPPET); + } + if (!TextUtils.isEmpty(folderName)) { + ps.println(String.format(getFormat(FORMAT_FOLDER_NAME), folderName)); + } + String folderId = folderCursor.getString(NOTE_COLUMN_ID); + exportFolderToText(folderId, ps); + } while (folderCursor.moveToNext()); + } + folderCursor.close(); + } + + // Export notes in root's folder + Cursor noteCursor = mContext.getContentResolver().query( + Notes.CONTENT_NOTE_URI, + NOTE_PROJECTION, + NoteColumns.TYPE + "=" + +Notes.TYPE_NOTE + " AND " + NoteColumns.PARENT_ID + + "=0", null, null); + + if (noteCursor != null) { + if (noteCursor.moveToFirst()) { + do { + ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format( + mContext.getString(R.string.format_datetime_mdhm), + noteCursor.getLong(NOTE_COLUMN_MODIFIED_DATE)))); + // Query data belong to this note + String noteId = noteCursor.getString(NOTE_COLUMN_ID); + exportNoteToText(noteId, ps); + } while (noteCursor.moveToNext()); + } + noteCursor.close(); + } + ps.close(); + + return STATE_SUCCESS; + } + + /** + * Get a print stream pointed to the file {@generateExportedTextFile} + */ + private PrintStream getExportToTextPrintStream() { + File file = generateFileMountedOnSDcard(mContext, R.string.file_path, + R.string.file_name_txt_format); + if (file == null) { + Log.e(TAG, "create file to exported failed"); + return null; + } + mFileName = file.getName(); + mFileDirectory = mContext.getString(R.string.file_path); + PrintStream ps = null; + try { + FileOutputStream fos = new FileOutputStream(file); + ps = new PrintStream(fos); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } catch (NullPointerException e) { + e.printStackTrace(); + return null; + } + return ps; + } + } + + /** + * Generate the text file to store imported data + */ + private static File generateFileMountedOnSDcard(Context context, int filePathResId, int fileNameFormatResId) { + StringBuilder sb = new StringBuilder(); + sb.append(Environment.getExternalStorageDirectory()); + sb.append(context.getString(filePathResId)); + File filedir = new File(sb.toString()); + sb.append(context.getString( + fileNameFormatResId, + DateFormat.format(context.getString(R.string.format_date_ymd), + System.currentTimeMillis()))); + File file = new File(sb.toString()); + + try { + if (!filedir.exists()) { + filedir.mkdir(); + } + if (!file.exists()) { + file.createNewFile(); + } + return file; + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } +} + + diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/DataUtils.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/DataUtils.java new file mode 100644 index 0000000..2a14982 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/DataUtils.java @@ -0,0 +1,295 @@ +/* + * 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.tool; + +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.OperationApplicationException; +import android.database.Cursor; +import android.os.RemoteException; +import android.util.Log; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.CallNote; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute; + +import java.util.ArrayList; +import java.util.HashSet; + + +public class DataUtils { + public static final String TAG = "DataUtils"; + public static boolean batchDeleteNotes(ContentResolver resolver, HashSet ids) { + if (ids == null) { + Log.d(TAG, "the ids is null"); + return true; + } + if (ids.size() == 0) { + Log.d(TAG, "no id is in the hashset"); + return true; + } + + ArrayList operationList = new ArrayList(); + for (long id : ids) { + if(id == Notes.ID_ROOT_FOLDER) { + Log.e(TAG, "Don't delete system folder root"); + continue; + } + ContentProviderOperation.Builder builder = ContentProviderOperation + .newDelete(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id)); + operationList.add(builder.build()); + } + try { + ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList); + if (results == null || results.length == 0 || results[0] == null) { + Log.d(TAG, "delete notes failed, ids:" + ids.toString()); + return false; + } + return true; + } catch (RemoteException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } catch (OperationApplicationException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } + return false; + } + + public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.PARENT_ID, desFolderId); + values.put(NoteColumns.ORIGIN_PARENT_ID, srcFolderId); + values.put(NoteColumns.LOCAL_MODIFIED, 1); + resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null); + } + + public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids, + long folderId) { + if (ids == null) { + Log.d(TAG, "the ids is null"); + return true; + } + + ArrayList operationList = new ArrayList(); + for (long id : ids) { + ContentProviderOperation.Builder builder = ContentProviderOperation + .newUpdate(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id)); + builder.withValue(NoteColumns.PARENT_ID, folderId); + builder.withValue(NoteColumns.LOCAL_MODIFIED, 1); + operationList.add(builder.build()); + } + + try { + ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList); + if (results == null || results.length == 0 || results[0] == null) { + Log.d(TAG, "delete notes failed, ids:" + ids.toString()); + return false; + } + return true; + } catch (RemoteException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } catch (OperationApplicationException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } + return false; + } + + /** + * Get the all folder count except system folders {@link Notes#TYPE_SYSTEM}} + */ + public static int getUserFolderCount(ContentResolver resolver) { + Cursor cursor =resolver.query(Notes.CONTENT_NOTE_URI, + new String[] { "COUNT(*)" }, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>?", + new String[] { String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER)}, + null); + + int count = 0; + if(cursor != null) { + if(cursor.moveToFirst()) { + try { + count = cursor.getInt(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "get folder count failed:" + e.toString()); + } finally { + cursor.close(); + } + } + } + return count; + } + + public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) { + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), + null, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER, + new String [] {String.valueOf(type)}, + null); + + boolean exist = false; + if (cursor != null) { + if (cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) { + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), + null, null, null, null); + + boolean exist = false; + if (cursor != null) { + if (cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static boolean existInDataDatabase(ContentResolver resolver, long dataId) { + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), + null, null, null, null); + + boolean exist = false; + if (cursor != null) { + if (cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static boolean checkVisibleFolderName(ContentResolver resolver, String name) { + Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, null, + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + + " AND " + NoteColumns.SNIPPET + "=?", + new String[] { name }, null); + boolean exist = false; + if(cursor != null) { + if(cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static HashSet getFolderNoteWidget(ContentResolver resolver, long folderId) { + Cursor c = resolver.query(Notes.CONTENT_NOTE_URI, + new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE }, + NoteColumns.PARENT_ID + "=?", + new String[] { String.valueOf(folderId) }, + null); + + HashSet set = null; + if (c != null) { + if (c.moveToFirst()) { + set = new HashSet(); + do { + try { + AppWidgetAttribute widget = new AppWidgetAttribute(); + widget.widgetId = c.getInt(0); + widget.widgetType = c.getInt(1); + set.add(widget); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, e.toString()); + } + } while (c.moveToNext()); + } + c.close(); + } + return set; + } + + public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) { + Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, + new String [] { CallNote.PHONE_NUMBER }, + CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?", + new String [] { String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE }, + null); + + if (cursor != null && cursor.moveToFirst()) { + try { + return cursor.getString(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "Get call number fails " + e.toString()); + } finally { + cursor.close(); + } + } + return ""; + } + + public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) { + Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, + new String [] { CallNote.NOTE_ID }, + CallNote.CALL_DATE + "=? AND " + CallNote.MIME_TYPE + "=? AND PHONE_NUMBERS_EQUAL(" + + CallNote.PHONE_NUMBER + ",?)", + new String [] { String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber }, + null); + + if (cursor != null) { + if (cursor.moveToFirst()) { + try { + return cursor.getLong(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "Get call note id fails " + e.toString()); + } + } + cursor.close(); + } + return 0; + } + + public static String getSnippetById(ContentResolver resolver, long noteId) { + Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, + new String [] { NoteColumns.SNIPPET }, + NoteColumns.ID + "=?", + new String [] { String.valueOf(noteId)}, + null); + + if (cursor != null) { + String snippet = ""; + if (cursor.moveToFirst()) { + snippet = cursor.getString(0); + } + cursor.close(); + return snippet; + } + throw new IllegalArgumentException("Note is not found with id: " + noteId); + } + + public static String getFormattedSnippet(String snippet) { + if (snippet != null) { + snippet = snippet.trim(); + int index = snippet.indexOf('\n'); + if (index != -1) { + snippet = snippet.substring(0, index); + } + } + return snippet; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/GTaskStringUtils.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/GTaskStringUtils.java new file mode 100644 index 0000000..666b729 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/GTaskStringUtils.java @@ -0,0 +1,113 @@ +/* + * 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.tool; + +public class GTaskStringUtils { + + public final static String GTASK_JSON_ACTION_ID = "action_id"; + + public final static String GTASK_JSON_ACTION_LIST = "action_list"; + + public final static String GTASK_JSON_ACTION_TYPE = "action_type"; + + public final static String GTASK_JSON_ACTION_TYPE_CREATE = "create"; + + public final static String GTASK_JSON_ACTION_TYPE_GETALL = "get_all"; + + public final static String GTASK_JSON_ACTION_TYPE_MOVE = "move"; + + public final static String GTASK_JSON_ACTION_TYPE_UPDATE = "update"; + + public final static String GTASK_JSON_CREATOR_ID = "creator_id"; + + public final static String GTASK_JSON_CHILD_ENTITY = "child_entity"; + + public final static String GTASK_JSON_CLIENT_VERSION = "client_version"; + + public final static String GTASK_JSON_COMPLETED = "completed"; + + public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id"; + + public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id"; + + public final static String GTASK_JSON_DELETED = "deleted"; + + public final static String GTASK_JSON_DEST_LIST = "dest_list"; + + public final static String GTASK_JSON_DEST_PARENT = "dest_parent"; + + public final static String GTASK_JSON_DEST_PARENT_TYPE = "dest_parent_type"; + + public final static String GTASK_JSON_ENTITY_DELTA = "entity_delta"; + + public final static String GTASK_JSON_ENTITY_TYPE = "entity_type"; + + public final static String GTASK_JSON_GET_DELETED = "get_deleted"; + + public final static String GTASK_JSON_ID = "id"; + + public final static String GTASK_JSON_INDEX = "index"; + + public final static String GTASK_JSON_LAST_MODIFIED = "last_modified"; + + public final static String GTASK_JSON_LATEST_SYNC_POINT = "latest_sync_point"; + + public final static String GTASK_JSON_LIST_ID = "list_id"; + + public final static String GTASK_JSON_LISTS = "lists"; + + public final static String GTASK_JSON_NAME = "name"; + + public final static String GTASK_JSON_NEW_ID = "new_id"; + + public final static String GTASK_JSON_NOTES = "notes"; + + public final static String GTASK_JSON_PARENT_ID = "parent_id"; + + public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id"; + + public final static String GTASK_JSON_RESULTS = "results"; + + public final static String GTASK_JSON_SOURCE_LIST = "source_list"; + + public final static String GTASK_JSON_TASKS = "tasks"; + + public final static String GTASK_JSON_TYPE = "type"; + + public final static String GTASK_JSON_TYPE_GROUP = "GROUP"; + + public final static String GTASK_JSON_TYPE_TASK = "TASK"; + + public final static String GTASK_JSON_USER = "user"; + + public final static String MIUI_FOLDER_PREFFIX = "[MIUI_Notes]"; + + public final static String FOLDER_DEFAULT = "Default"; + + public final static String FOLDER_CALL_NOTE = "Call_Note"; + + public final static String FOLDER_META = "METADATA"; + + public final static String META_HEAD_GTASK_ID = "meta_gid"; + + public final static String META_HEAD_NOTE = "meta_note"; + + public final static String META_HEAD_DATA = "meta_data"; + + public final static String META_NOTE_NAME = "[META INFO] DON'T UPDATE AND DELETE"; + +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/ResourceParser.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/ResourceParser.java new file mode 100644 index 0000000..1ad3ad6 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/tool/ResourceParser.java @@ -0,0 +1,181 @@ +/* + * 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.tool; + +import android.content.Context; +import android.preference.PreferenceManager; + +import net.micode.notes.R; +import net.micode.notes.ui.NotesPreferenceActivity; + +public class ResourceParser { + + public static final int YELLOW = 0; + public static final int BLUE = 1; + public static final int WHITE = 2; + public static final int GREEN = 3; + public static final int RED = 4; + + public static final int BG_DEFAULT_COLOR = YELLOW; + + public static final int TEXT_SMALL = 0; + public static final int TEXT_MEDIUM = 1; + public static final int TEXT_LARGE = 2; + public static final int TEXT_SUPER = 3; + + public static final int BG_DEFAULT_FONT_SIZE = TEXT_MEDIUM; + + public static class NoteBgResources { + private final static int [] BG_EDIT_RESOURCES = new int [] { + R.drawable.edit_yellow, + R.drawable.edit_blue, + R.drawable.edit_white, + R.drawable.edit_green, + R.drawable.edit_red + }; + + private final static int [] BG_EDIT_TITLE_RESOURCES = new int [] { + R.drawable.edit_title_yellow, + R.drawable.edit_title_blue, + R.drawable.edit_title_white, + R.drawable.edit_title_green, + R.drawable.edit_title_red + }; + + public static int getNoteBgResource(int id) { + return BG_EDIT_RESOURCES[id]; + } + + public static int getNoteTitleBgResource(int id) { + return BG_EDIT_TITLE_RESOURCES[id]; + } + } + + public static int getDefaultBgId(Context context) { + if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean( + NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) { + return (int) (Math.random() * NoteBgResources.BG_EDIT_RESOURCES.length); + } else { + return BG_DEFAULT_COLOR; + } + } + + public static class NoteItemBgResources { + private final static int [] BG_FIRST_RESOURCES = new int [] { + R.drawable.list_yellow_up, + R.drawable.list_blue_up, + R.drawable.list_white_up, + R.drawable.list_green_up, + R.drawable.list_red_up + }; + + private final static int [] BG_NORMAL_RESOURCES = new int [] { + R.drawable.list_yellow_middle, + R.drawable.list_blue_middle, + R.drawable.list_white_middle, + R.drawable.list_green_middle, + R.drawable.list_red_middle + }; + + private final static int [] BG_LAST_RESOURCES = new int [] { + R.drawable.list_yellow_down, + R.drawable.list_blue_down, + R.drawable.list_white_down, + R.drawable.list_green_down, + R.drawable.list_red_down, + }; + + private final static int [] BG_SINGLE_RESOURCES = new int [] { + R.drawable.list_yellow_single, + R.drawable.list_blue_single, + R.drawable.list_white_single, + R.drawable.list_green_single, + R.drawable.list_red_single + }; + + public static int getNoteBgFirstRes(int id) { + return BG_FIRST_RESOURCES[id]; + } + + public static int getNoteBgLastRes(int id) { + return BG_LAST_RESOURCES[id]; + } + + public static int getNoteBgSingleRes(int id) { + return BG_SINGLE_RESOURCES[id]; + } + + public static int getNoteBgNormalRes(int id) { + return BG_NORMAL_RESOURCES[id]; + } + + public static int getFolderBgRes() { + return R.drawable.list_folder; + } + } + + public static class WidgetBgResources { + private final static int [] BG_2X_RESOURCES = new int [] { + R.drawable.widget_2x_yellow, + R.drawable.widget_2x_blue, + R.drawable.widget_2x_white, + R.drawable.widget_2x_green, + R.drawable.widget_2x_red, + }; + + public static int getWidget2xBgResource(int id) { + return BG_2X_RESOURCES[id]; + } + + private final static int [] BG_4X_RESOURCES = new int [] { + R.drawable.widget_4x_yellow, + R.drawable.widget_4x_blue, + R.drawable.widget_4x_white, + R.drawable.widget_4x_green, + R.drawable.widget_4x_red + }; + + public static int getWidget4xBgResource(int id) { + return BG_4X_RESOURCES[id]; + } + } + + public static class TextAppearanceResources { + private final static int [] TEXTAPPEARANCE_RESOURCES = new int [] { + R.style.TextAppearanceNormal, + R.style.TextAppearanceMedium, + R.style.TextAppearanceLarge, + R.style.TextAppearanceSuper + }; + + public static int getTexAppearanceResource(int id) { + /** + * HACKME: Fix bug of store the resource id in shared preference. + * The id may larger than the length of resources, in this case, + * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE} + */ + if (id >= TEXTAPPEARANCE_RESOURCES.length) { + return BG_DEFAULT_FONT_SIZE; + } + return TEXTAPPEARANCE_RESOURCES[id]; + } + + public static int getResourcesSize() { + return TEXTAPPEARANCE_RESOURCES.length; + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmAlertActivity.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmAlertActivity.java new file mode 100644 index 0000000..85723be --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmAlertActivity.java @@ -0,0 +1,158 @@ +/* + * 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.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.DialogInterface.OnDismissListener; +import android.content.Intent; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Bundle; +import android.os.PowerManager; +import android.provider.Settings; +import android.view.Window; +import android.view.WindowManager; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.DataUtils; + +import java.io.IOException; + + +public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { + private long mNoteId; + private String mSnippet; + private static final int SNIPPET_PREW_MAX_LEN = 60; + MediaPlayer mPlayer; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + + final Window win = getWindow(); + win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + + if (!isScreenOn()) { + win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON + | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); + } + + Intent intent = getIntent(); + + try { + mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); + mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); + mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, + SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) + : mSnippet; + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return; + } + + mPlayer = new MediaPlayer(); + if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { + showActionDialog(); + playAlarmSound(); + } else { + finish(); + } + } + + private boolean isScreenOn() { + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + return pm.isScreenOn(); + } + + private void playAlarmSound() { + Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); + + int silentModeStreams = Settings.System.getInt(getContentResolver(), + Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); + + if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { + mPlayer.setAudioStreamType(silentModeStreams); + } else { + mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); + } + try { + mPlayer.setDataSource(this, url); + mPlayer.prepare(); + mPlayer.setLooping(true); + mPlayer.start(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private void showActionDialog() { + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle(R.string.app_name); + dialog.setMessage(mSnippet); + dialog.setPositiveButton(R.string.notealert_ok, this); + if (isScreenOn()) { + dialog.setNegativeButton(R.string.notealert_enter, this); + } + dialog.show().setOnDismissListener(this); + } + + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_NEGATIVE: + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.putExtra(Intent.EXTRA_UID, mNoteId); + startActivity(intent); + break; + default: + break; + } + } + + public void onDismiss(DialogInterface dialog) { + stopAlarmSound(); + finish(); + } + + private void stopAlarmSound() { + if (mPlayer != null) { + mPlayer.stop(); + mPlayer.release(); + mPlayer = null; + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmInitReceiver.java new file mode 100644 index 0000000..f221202 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmInitReceiver.java @@ -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.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; + + +public class AlarmInitReceiver extends BroadcastReceiver { + + private static final String [] PROJECTION = new String [] { + NoteColumns.ID, + NoteColumns.ALERTED_DATE + }; + + private static final int COLUMN_ID = 0; + private static final int COLUMN_ALERTED_DATE = 1; + + @Override + public void onReceive(Context context, Intent intent) { + long currentDate = System.currentTimeMillis(); + Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, + PROJECTION, + NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, + new String[] { String.valueOf(currentDate) }, + null); + + if (c != null) { + if (c.moveToFirst()) { + do { + long alertDate = c.getLong(COLUMN_ALERTED_DATE); + Intent sender = new Intent(context, AlarmReceiver.class); + sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); + AlarmManager alermManager = (AlarmManager) context + .getSystemService(Context.ALARM_SERVICE); + alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); + } while (c.moveToNext()); + } + c.close(); + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmReceiver.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmReceiver.java new file mode 100644 index 0000000..54e503b --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/AlarmReceiver.java @@ -0,0 +1,30 @@ +/* + * 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.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class AlarmReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + intent.setClass(context, AlarmAlertActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePicker.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePicker.java new file mode 100644 index 0000000..496b0cd --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePicker.java @@ -0,0 +1,485 @@ +/* + * 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 java.text.DateFormatSymbols; +import java.util.Calendar; + +import net.micode.notes.R; + + +import android.content.Context; +import android.text.format.DateFormat; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.NumberPicker; + +public class DateTimePicker extends FrameLayout { + + private static final boolean DEFAULT_ENABLE_STATE = true; + + private static final int HOURS_IN_HALF_DAY = 12; + private static final int HOURS_IN_ALL_DAY = 24; + private static final int DAYS_IN_ALL_WEEK = 7; + private static final int DATE_SPINNER_MIN_VAL = 0; + private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1; + private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0; + private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23; + private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1; + private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12; + private static final int MINUT_SPINNER_MIN_VAL = 0; + private static final int MINUT_SPINNER_MAX_VAL = 59; + private static final int AMPM_SPINNER_MIN_VAL = 0; + private static final int AMPM_SPINNER_MAX_VAL = 1; + + private final NumberPicker mDateSpinner; + private final NumberPicker mHourSpinner; + private final NumberPicker mMinuteSpinner; + private final NumberPicker mAmPmSpinner; + private Calendar mDate; + + private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; + + private boolean mIsAm; + + private boolean mIs24HourView; + + private boolean mIsEnabled = DEFAULT_ENABLE_STATE; + + private boolean mInitialising; + + private OnDateTimeChangedListener mOnDateTimeChangedListener; + + private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); + updateDateControl(); + onDateTimeChanged(); + } + }; + + private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + boolean isDateChanged = false; + Calendar cal = Calendar.getInstance(); + if (!mIs24HourView) { + if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, 1); + isDateChanged = true; + } else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, -1); + isDateChanged = true; + } + if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || + oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + } else { + if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, 1); + isDateChanged = true; + } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, -1); + isDateChanged = true; + } + } + int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); + mDate.set(Calendar.HOUR_OF_DAY, newHour); + onDateTimeChanged(); + if (isDateChanged) { + setCurrentYear(cal.get(Calendar.YEAR)); + setCurrentMonth(cal.get(Calendar.MONTH)); + setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); + } + } + }; + + private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + int minValue = mMinuteSpinner.getMinValue(); + int maxValue = mMinuteSpinner.getMaxValue(); + int offset = 0; + if (oldVal == maxValue && newVal == minValue) { + offset += 1; + } else if (oldVal == minValue && newVal == maxValue) { + offset -= 1; + } + if (offset != 0) { + mDate.add(Calendar.HOUR_OF_DAY, offset); + mHourSpinner.setValue(getCurrentHour()); + updateDateControl(); + int newHour = getCurrentHourOfDay(); + if (newHour >= HOURS_IN_HALF_DAY) { + mIsAm = false; + updateAmPmControl(); + } else { + mIsAm = true; + updateAmPmControl(); + } + } + mDate.set(Calendar.MINUTE, newVal); + onDateTimeChanged(); + } + }; + + private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + mIsAm = !mIsAm; + if (mIsAm) { + mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY); + } else { + mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY); + } + updateAmPmControl(); + onDateTimeChanged(); + } + }; + + public interface OnDateTimeChangedListener { + void onDateTimeChanged(DateTimePicker view, int year, int month, + int dayOfMonth, int hourOfDay, int minute); + } + + public DateTimePicker(Context context) { + this(context, System.currentTimeMillis()); + } + + public DateTimePicker(Context context, long date) { + this(context, date, DateFormat.is24HourFormat(context)); + } + + public DateTimePicker(Context context, long date, boolean is24HourView) { + super(context); + mDate = Calendar.getInstance(); + mInitialising = true; + mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; + inflate(context, R.layout.datetime_picker, this); + + mDateSpinner = (NumberPicker) findViewById(R.id.date); + mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); + mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); + mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); + + mHourSpinner = (NumberPicker) findViewById(R.id.hour); + mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); + mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); + mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); + mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); + mMinuteSpinner.setOnLongPressUpdateInterval(100); + mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); + + String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); + mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); + mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL); + mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL); + mAmPmSpinner.setDisplayedValues(stringsForAmPm); + mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); + + // update controls to initial state + updateDateControl(); + updateHourControl(); + updateAmPmControl(); + + set24HourView(is24HourView); + + // set to current time + setCurrentDate(date); + + setEnabled(isEnabled()); + + // set the content descriptions + mInitialising = false; + } + + @Override + public void setEnabled(boolean enabled) { + if (mIsEnabled == enabled) { + return; + } + super.setEnabled(enabled); + mDateSpinner.setEnabled(enabled); + mMinuteSpinner.setEnabled(enabled); + mHourSpinner.setEnabled(enabled); + mAmPmSpinner.setEnabled(enabled); + mIsEnabled = enabled; + } + + @Override + public boolean isEnabled() { + return mIsEnabled; + } + + /** + * Get the current date in millis + * + * @return the current date in millis + */ + public long getCurrentDateInTimeMillis() { + return mDate.getTimeInMillis(); + } + + /** + * Set the current date + * + * @param date The current date in millis + */ + public void setCurrentDate(long date) { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(date); + setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), + cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); + } + + /** + * Set the current date + * + * @param year The current year + * @param month The current month + * @param dayOfMonth The current dayOfMonth + * @param hourOfDay The current hourOfDay + * @param minute The current minute + */ + public void setCurrentDate(int year, int month, + int dayOfMonth, int hourOfDay, int minute) { + setCurrentYear(year); + setCurrentMonth(month); + setCurrentDay(dayOfMonth); + setCurrentHour(hourOfDay); + setCurrentMinute(minute); + } + + /** + * Get current year + * + * @return The current year + */ + public int getCurrentYear() { + return mDate.get(Calendar.YEAR); + } + + /** + * Set current year + * + * @param year The current year + */ + public void setCurrentYear(int year) { + if (!mInitialising && year == getCurrentYear()) { + return; + } + mDate.set(Calendar.YEAR, year); + updateDateControl(); + onDateTimeChanged(); + } + + /** + * Get current month in the year + * + * @return The current month in the year + */ + public int getCurrentMonth() { + return mDate.get(Calendar.MONTH); + } + + /** + * Set current month in the year + * + * @param month The month in the year + */ + public void setCurrentMonth(int month) { + if (!mInitialising && month == getCurrentMonth()) { + return; + } + mDate.set(Calendar.MONTH, month); + updateDateControl(); + onDateTimeChanged(); + } + + /** + * Get current day of the month + * + * @return The day of the month + */ + public int getCurrentDay() { + return mDate.get(Calendar.DAY_OF_MONTH); + } + + /** + * Set current day of the month + * + * @param dayOfMonth The day of the month + */ + public void setCurrentDay(int dayOfMonth) { + if (!mInitialising && dayOfMonth == getCurrentDay()) { + return; + } + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + updateDateControl(); + onDateTimeChanged(); + } + + /** + * Get current hour in 24 hour mode, in the range (0~23) + * @return The current hour in 24 hour mode + */ + public int getCurrentHourOfDay() { + return mDate.get(Calendar.HOUR_OF_DAY); + } + + private int getCurrentHour() { + if (mIs24HourView){ + return getCurrentHourOfDay(); + } else { + int hour = getCurrentHourOfDay(); + if (hour > HOURS_IN_HALF_DAY) { + return hour - HOURS_IN_HALF_DAY; + } else { + return hour == 0 ? HOURS_IN_HALF_DAY : hour; + } + } + } + + /** + * Set current hour in 24 hour mode, in the range (0~23) + * + * @param hourOfDay + */ + public void setCurrentHour(int hourOfDay) { + if (!mInitialising && hourOfDay == getCurrentHourOfDay()) { + return; + } + mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + if (!mIs24HourView) { + if (hourOfDay >= HOURS_IN_HALF_DAY) { + mIsAm = false; + if (hourOfDay > HOURS_IN_HALF_DAY) { + hourOfDay -= HOURS_IN_HALF_DAY; + } + } else { + mIsAm = true; + if (hourOfDay == 0) { + hourOfDay = HOURS_IN_HALF_DAY; + } + } + updateAmPmControl(); + } + mHourSpinner.setValue(hourOfDay); + onDateTimeChanged(); + } + + /** + * Get currentMinute + * + * @return The Current Minute + */ + public int getCurrentMinute() { + return mDate.get(Calendar.MINUTE); + } + + /** + * Set current minute + */ + public void setCurrentMinute(int minute) { + if (!mInitialising && minute == getCurrentMinute()) { + return; + } + mMinuteSpinner.setValue(minute); + mDate.set(Calendar.MINUTE, minute); + onDateTimeChanged(); + } + + /** + * @return true if this is in 24 hour view else false. + */ + public boolean is24HourView () { + return mIs24HourView; + } + + /** + * Set whether in 24 hour or AM/PM mode. + * + * @param is24HourView True for 24 hour mode. False for AM/PM mode. + */ + public void set24HourView(boolean is24HourView) { + if (mIs24HourView == is24HourView) { + return; + } + mIs24HourView = is24HourView; + mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE); + int hour = getCurrentHourOfDay(); + updateHourControl(); + setCurrentHour(hour); + updateAmPmControl(); + } + + private void updateDateControl() { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); + mDateSpinner.setDisplayedValues(null); + for (int i = 0; i < DAYS_IN_ALL_WEEK; ++i) { + cal.add(Calendar.DAY_OF_YEAR, 1); + mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); + } + mDateSpinner.setDisplayedValues(mDateDisplayValues); + mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); + mDateSpinner.invalidate(); + } + + private void updateAmPmControl() { + if (mIs24HourView) { + mAmPmSpinner.setVisibility(View.GONE); + } else { + int index = mIsAm ? Calendar.AM : Calendar.PM; + mAmPmSpinner.setValue(index); + mAmPmSpinner.setVisibility(View.VISIBLE); + } + } + + private void updateHourControl() { + if (mIs24HourView) { + mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW); + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); + } else { + mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); + } + } + + /** + * Set the callback that indicates the 'Set' button has been pressed. + * @param callback the callback, if null will do nothing + */ + public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { + mOnDateTimeChangedListener = callback; + } + + private void onDateTimeChanged() { + if (mOnDateTimeChangedListener != null) { + mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(), + getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePickerDialog.java new file mode 100644 index 0000000..2c47ba4 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DateTimePickerDialog.java @@ -0,0 +1,90 @@ +/* + * 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 java.util.Calendar; + +import net.micode.notes.R; +import net.micode.notes.ui.DateTimePicker; +import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.text.format.DateFormat; +import android.text.format.DateUtils; + +public class DateTimePickerDialog extends AlertDialog implements OnClickListener { + + private Calendar mDate = Calendar.getInstance(); + private boolean mIs24HourView; + private OnDateTimeSetListener mOnDateTimeSetListener; + private DateTimePicker mDateTimePicker; + + public interface OnDateTimeSetListener { + void OnDateTimeSet(AlertDialog dialog, long date); + } + + public DateTimePickerDialog(Context context, long date) { + super(context); + mDateTimePicker = new DateTimePicker(context); + setView(mDateTimePicker); + mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { + public void onDateTimeChanged(DateTimePicker view, int year, int month, + int dayOfMonth, int hourOfDay, int minute) { + mDate.set(Calendar.YEAR, year); + mDate.set(Calendar.MONTH, month); + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + mDate.set(Calendar.MINUTE, minute); + updateTitle(mDate.getTimeInMillis()); + } + }); + mDate.setTimeInMillis(date); + mDate.set(Calendar.SECOND, 0); + mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); + setButton(context.getString(R.string.datetime_dialog_ok), this); + setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); + set24HourView(DateFormat.is24HourFormat(this.getContext())); + updateTitle(mDate.getTimeInMillis()); + } + + public void set24HourView(boolean is24HourView) { + mIs24HourView = is24HourView; + } + + public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { + mOnDateTimeSetListener = callBack; + } + + private void updateTitle(long date) { + int flag = + DateUtils.FORMAT_SHOW_YEAR | + DateUtils.FORMAT_SHOW_DATE | + DateUtils.FORMAT_SHOW_TIME; + flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; + setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); + } + + public void onClick(DialogInterface arg0, int arg1) { + if (mOnDateTimeSetListener != null) { + mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); + } + } + +} \ No newline at end of file diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DropdownMenu.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DropdownMenu.java new file mode 100644 index 0000000..613dc74 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/DropdownMenu.java @@ -0,0 +1,61 @@ +/* + * 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; + + 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); + } + } + + public MenuItem findItem(int id) { + return mMenu.findItem(id); + } + + public void setTitle(CharSequence title) { + mButton.setText(title); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/FoldersListAdapter.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/FoldersListAdapter.java new file mode 100644 index 0000000..96b77da --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/FoldersListAdapter.java @@ -0,0 +1,80 @@ +/* + * 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 { + public static final String [] PROJECTION = { + NoteColumns.ID, + NoteColumns.SNIPPET + }; + + public static final int ID_COLUMN = 0; + 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) { + 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 { + 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); + } + } + +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditActivity.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditActivity.java new file mode 100644 index 0000000..96a9ff8 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditActivity.java @@ -0,0 +1,873 @@ +/* + * 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.app.Activity; +import android.app.AlarmManager; +import android.app.AlertDialog; +import android.app.PendingIntent; +import android.app.SearchManager; +import android.appwidget.AppWidgetManager; +import android.content.ContentUris; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Paint; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.format.DateUtils; +import android.text.style.BackgroundColorSpan; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.TextNote; +import net.micode.notes.model.WorkingNote; +import net.micode.notes.model.WorkingNote.NoteSettingChangedListener; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.ResourceParser; +import net.micode.notes.tool.ResourceParser.TextAppearanceResources; +import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener; +import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener; +import net.micode.notes.widget.NoteWidgetProvider_2x; +import net.micode.notes.widget.NoteWidgetProvider_4x; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class NoteEditActivity extends Activity implements OnClickListener, + NoteSettingChangedListener, OnTextViewChangeListener { + private class HeadViewHolder { + public TextView tvModified; + + public ImageView ivAlertIcon; + + public TextView tvAlertDate; + + public ImageView ibSetBgColor; + } + + private static final Map sBgSelectorBtnsMap = new HashMap(); + static { + sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); + sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED); + sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE); + sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN); + sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE); + } + + private static final Map sBgSelectorSelectionMap = new HashMap(); + static { + sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select); + sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select); + sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select); + sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select); + sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); + } + + private static final Map sFontSizeBtnsMap = new HashMap(); + static { + sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE); + sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL); + sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM); + sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); + } + + private static final Map sFontSelectorSelectionMap = new HashMap(); + static { + sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); + } + + private static final String TAG = "NoteEditActivity"; + + private HeadViewHolder mNoteHeaderHolder; + + private View mHeadViewPanel; + + private View mNoteBgColorSelector; + + private View mFontSizeSelector; + + private EditText mNoteEditor; + + private View mNoteEditorPanel; + + private WorkingNote mWorkingNote; + + private SharedPreferences mSharedPrefs; + private int mFontSizeId; + + private static final String PREFERENCE_FONT_SIZE = "pref_font_size"; + + private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10; + + public static final String TAG_CHECKED = String.valueOf('\u221A'); + public static final String TAG_UNCHECKED = String.valueOf('\u25A1'); + + private LinearLayout mEditTextList; + + private String mUserQuery; + private Pattern mPattern; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.note_edit); + + if (savedInstanceState == null && !initActivityState(getIntent())) { + finish(); + return; + } + initResources(); + } + + /** + * Current activity may be killed when the memory is low. Once it is killed, for another time + * user load this activity, we should restore the former state + */ + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID)); + if (!initActivityState(intent)) { + finish(); + return; + } + Log.d(TAG, "Restoring from killed activity"); + } + } + + private boolean initActivityState(Intent intent) { + /** + * If the user specified the {@link Intent#ACTION_VIEW} but not provided with id, + * then jump to the NotesListActivity + */ + mWorkingNote = null; + if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) { + long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); + mUserQuery = ""; + + /** + * Starting from the searched result + */ + if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) { + noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); + mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); + } + + if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) { + Intent jump = new Intent(this, NotesListActivity.class); + startActivity(jump); + showToast(R.string.error_note_not_exist); + finish(); + return false; + } else { + mWorkingNote = WorkingNote.load(this, noteId); + if (mWorkingNote == null) { + Log.e(TAG, "load note failed with note id" + noteId); + finish(); + return false; + } + } + getWindow().setSoftInputMode( + WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { + // New note + long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); + int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + int widgetType = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, + Notes.TYPE_WIDGET_INVALIDE); + int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, + ResourceParser.getDefaultBgId(this)); + + // Parse call-record note + String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); + long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0); + if (callDate != 0 && phoneNumber != null) { + if (TextUtils.isEmpty(phoneNumber)) { + Log.w(TAG, "The call record number is null"); + } + long noteId = 0; + if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(), + phoneNumber, callDate)) > 0) { + mWorkingNote = WorkingNote.load(this, noteId); + if (mWorkingNote == null) { + Log.e(TAG, "load call note failed with note id" + noteId); + finish(); + return false; + } + } else { + mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, + widgetType, bgResId); + mWorkingNote.convertToCallNote(phoneNumber, callDate); + } + } else { + mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, + bgResId); + } + + getWindow().setSoftInputMode( + WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE + | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } else { + Log.e(TAG, "Intent not specified action, should not support"); + finish(); + return false; + } + mWorkingNote.setOnSettingStatusChangedListener(this); + return true; + } + + @Override + protected void onResume() { + super.onResume(); + initNoteScreen(); + } + + private void initNoteScreen() { + mNoteEditor.setTextAppearance(this, TextAppearanceResources + .getTexAppearanceResource(mFontSizeId)); + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + switchToListMode(mWorkingNote.getContent()); + } else { + mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); + mNoteEditor.setSelection(mNoteEditor.getText().length()); + } + for (Integer id : sBgSelectorSelectionMap.keySet()) { + findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE); + } + mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); + mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); + + mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this, + mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_SHOW_YEAR)); + + /** + * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker + * is not ready + */ + showAlertHeader(); + } + + private void showAlertHeader() { + if (mWorkingNote.hasClockAlert()) { + long time = System.currentTimeMillis(); + if (time > mWorkingNote.getAlertDate()) { + mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); + } else { + mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString( + mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS)); + } + mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE); + mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE); + } else { + mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); + mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); + }; + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + initActivityState(intent); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + /** + * For new note without note id, we should firstly save it to + * generate a id. If the editing note is not worth saving, there + * is no id which is equivalent to create new note + */ + if (!mWorkingNote.existInDatabase()) { + saveNote(); + } + outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState"); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (mNoteBgColorSelector.getVisibility() == View.VISIBLE + && !inRangeOfView(mNoteBgColorSelector, ev)) { + mNoteBgColorSelector.setVisibility(View.GONE); + return true; + } + + if (mFontSizeSelector.getVisibility() == View.VISIBLE + && !inRangeOfView(mFontSizeSelector, ev)) { + mFontSizeSelector.setVisibility(View.GONE); + return true; + } + return super.dispatchTouchEvent(ev); + } + + private boolean inRangeOfView(View view, MotionEvent ev) { + int []location = new int[2]; + view.getLocationOnScreen(location); + int x = location[0]; + int y = location[1]; + if (ev.getX() < x + || ev.getX() > (x + view.getWidth()) + || ev.getY() < y + || ev.getY() > (y + view.getHeight())) { + return false; + } + return true; + } + + private void initResources() { + mHeadViewPanel = findViewById(R.id.note_title); + mNoteHeaderHolder = new HeadViewHolder(); + mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date); + mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon); + mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date); + mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color); + mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this); + mNoteEditor = (EditText) findViewById(R.id.note_edit_view); + mNoteEditorPanel = findViewById(R.id.sv_note_edit); + mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector); + for (int id : sBgSelectorBtnsMap.keySet()) { + ImageView iv = (ImageView) findViewById(id); + iv.setOnClickListener(this); + } + + mFontSizeSelector = findViewById(R.id.font_size_selector); + for (int id : sFontSizeBtnsMap.keySet()) { + View view = findViewById(id); + view.setOnClickListener(this); + }; + mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); + /** + * HACKME: Fix bug of store the resource id in shared preference. + * The id may larger than the length of resources, in this case, + * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE} + */ + if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { + mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; + } + mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); + } + + @Override + protected void onPause() { + super.onPause(); + if(saveNote()) { + Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); + } + clearSettingState(); + } + + private void updateWidget() { + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) { + intent.setClass(this, NoteWidgetProvider_2x.class); + } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) { + intent.setClass(this, NoteWidgetProvider_4x.class); + } else { + Log.e(TAG, "Unspported widget type"); + return; + } + + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { + mWorkingNote.getWidgetId() + }); + + sendBroadcast(intent); + setResult(RESULT_OK, intent); + } + + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.btn_set_bg_color) { + mNoteBgColorSelector.setVisibility(View.VISIBLE); + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + - View.VISIBLE); + } else if (sBgSelectorBtnsMap.containsKey(id)) { + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + View.GONE); + mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id)); + mNoteBgColorSelector.setVisibility(View.GONE); + } else if (sFontSizeBtnsMap.containsKey(id)) { + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE); + mFontSizeId = sFontSizeBtnsMap.get(id); + mSharedPrefs.edit().putInt(PREFERENCE_FONT_SIZE, mFontSizeId).commit(); + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + getWorkingText(); + switchToListMode(mWorkingNote.getContent()); + } else { + mNoteEditor.setTextAppearance(this, + TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); + } + mFontSizeSelector.setVisibility(View.GONE); + } + } + + @Override + public void onBackPressed() { + if(clearSettingState()) { + return; + } + + saveNote(); + super.onBackPressed(); + } + + private boolean clearSettingState() { + if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { + mNoteBgColorSelector.setVisibility(View.GONE); + return true; + } else if (mFontSizeSelector.getVisibility() == View.VISIBLE) { + mFontSizeSelector.setVisibility(View.GONE); + return true; + } + return false; + } + + public void onBackgroundColorChanged() { + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + View.VISIBLE); + mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); + mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (isFinishing()) { + return true; + } + clearSettingState(); + menu.clear(); + if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) { + getMenuInflater().inflate(R.menu.call_note_edit, menu); + } else { + getMenuInflater().inflate(R.menu.note_edit, menu); + } + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_normal_mode); + } else { + menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode); + } + if (mWorkingNote.hasClockAlert()) { + menu.findItem(R.id.menu_alert).setVisible(false); + } else { + menu.findItem(R.id.menu_delete_remind).setVisible(false); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_new_note: + createNewNote(); + break; + case R.id.menu_delete: + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.alert_title_delete)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_note)); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + deleteCurrentNote(); + finish(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + break; + case R.id.menu_font_size: + mFontSizeSelector.setVisibility(View.VISIBLE); + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); + break; + case R.id.menu_list_mode: + mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ? + TextNote.MODE_CHECK_LIST : 0); + break; + case R.id.menu_share: + getWorkingText(); + sendTo(this, mWorkingNote.getContent()); + break; + case R.id.menu_send_to_desktop: + sendToDesktop(); + break; + case R.id.menu_alert: + setReminder(); + break; + case R.id.menu_delete_remind: + mWorkingNote.setAlertDate(0, false); + break; + default: + break; + } + return true; + } + + private void setReminder() { + DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis()); + d.setOnDateTimeSetListener(new OnDateTimeSetListener() { + public void OnDateTimeSet(AlertDialog dialog, long date) { + mWorkingNote.setAlertDate(date , true); + } + }); + d.show(); + } + + /** + * Share note to apps that support {@link Intent#ACTION_SEND} action + * and {@text/plain} type + */ + private void sendTo(Context context, String info) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_TEXT, info); + intent.setType("text/plain"); + context.startActivity(intent); + } + + private void createNewNote() { + // Firstly, save current editing notes + saveNote(); + + // For safety, start a new NoteEditActivity + finish(); + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_INSERT_OR_EDIT); + intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId()); + startActivity(intent); + } + + private void deleteCurrentNote() { + if (mWorkingNote.existInDatabase()) { + HashSet ids = new HashSet(); + long id = mWorkingNote.getNoteId(); + if (id != Notes.ID_ROOT_FOLDER) { + ids.add(id); + } else { + Log.d(TAG, "Wrong note id, should not happen"); + } + if (!isSyncMode()) { + if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) { + Log.e(TAG, "Delete Note error"); + } + } else { + if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) { + Log.e(TAG, "Move notes to trash folder error, should not happens"); + } + } + } + mWorkingNote.markDeleted(true); + } + + private boolean isSyncMode() { + return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; + } + + public void onClockAlertChanged(long date, boolean set) { + /** + * User could set clock to an unsaved note, so before setting the + * alert clock, we should save the note first + */ + if (!mWorkingNote.existInDatabase()) { + saveNote(); + } + if (mWorkingNote.getNoteId() > 0) { + Intent intent = new Intent(this, AlarmReceiver.class); + intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId())); + PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); + AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); + showAlertHeader(); + if(!set) { + alarmManager.cancel(pendingIntent); + } else { + alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); + } + } else { + /** + * There is the condition that user has input nothing (the note is + * not worthy saving), we have no note id, remind the user that he + * should input something + */ + Log.e(TAG, "Clock alert setting error"); + showToast(R.string.error_note_empty_for_clock); + } + } + + public void onWidgetChanged() { + updateWidget(); + } + + public void onEditTextDelete(int index, String text) { + int childCount = mEditTextList.getChildCount(); + if (childCount == 1) { + return; + } + + for (int i = index + 1; i < childCount; i++) { + ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) + .setIndex(i - 1); + } + + mEditTextList.removeViewAt(index); + NoteEditText edit = null; + if(index == 0) { + edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById( + R.id.et_edit_text); + } else { + edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById( + R.id.et_edit_text); + } + int length = edit.length(); + edit.append(text); + edit.requestFocus(); + edit.setSelection(length); + } + + public void onEditTextEnter(int index, String text) { + /** + * Should not happen, check for debug + */ + if(index > mEditTextList.getChildCount()) { + Log.e(TAG, "Index out of mEditTextList boundrary, should not happen"); + } + + View view = getListItem(text, index); + mEditTextList.addView(view, index); + NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + edit.requestFocus(); + edit.setSelection(0); + for (int i = index + 1; i < mEditTextList.getChildCount(); i++) { + ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) + .setIndex(i); + } + } + + private void switchToListMode(String text) { + mEditTextList.removeAllViews(); + String[] items = text.split("\n"); + int index = 0; + for (String item : items) { + if(!TextUtils.isEmpty(item)) { + mEditTextList.addView(getListItem(item, index)); + index++; + } + } + mEditTextList.addView(getListItem("", index)); + mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); + + mNoteEditor.setVisibility(View.GONE); + mEditTextList.setVisibility(View.VISIBLE); + } + + private Spannable getHighlightQueryResult(String fullText, String userQuery) { + SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); + if (!TextUtils.isEmpty(userQuery)) { + mPattern = Pattern.compile(userQuery); + Matcher m = mPattern.matcher(fullText); + int start = 0; + while (m.find(start)) { + spannable.setSpan( + new BackgroundColorSpan(this.getResources().getColor( + R.color.user_query_highlight)), m.start(), m.end(), + Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + start = m.end(); + } + } + return spannable; + } + + private View getListItem(String item, int index) { + View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null); + final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); + CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item)); + cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + } else { + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + } + } + }); + + if (item.startsWith(TAG_CHECKED)) { + cb.setChecked(true); + edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + item = item.substring(TAG_CHECKED.length(), item.length()).trim(); + } else if (item.startsWith(TAG_UNCHECKED)) { + cb.setChecked(false); + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); + } + + edit.setOnTextViewChangeListener(this); + edit.setIndex(index); + edit.setText(getHighlightQueryResult(item, mUserQuery)); + return view; + } + + public void onTextChange(int index, boolean hasText) { + if (index >= mEditTextList.getChildCount()) { + Log.e(TAG, "Wrong index, should not happen"); + return; + } + if(hasText) { + mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE); + } else { + mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE); + } + } + + public void onCheckListModeChanged(int oldMode, int newMode) { + if (newMode == TextNote.MODE_CHECK_LIST) { + switchToListMode(mNoteEditor.getText().toString()); + } else { + if (!getWorkingText()) { + mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", + "")); + } + mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); + mEditTextList.setVisibility(View.GONE); + mNoteEditor.setVisibility(View.VISIBLE); + } + } + + private boolean getWorkingText() { + boolean hasChecked = false; + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < mEditTextList.getChildCount(); i++) { + View view = mEditTextList.getChildAt(i); + NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + if (!TextUtils.isEmpty(edit.getText())) { + if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) { + sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n"); + hasChecked = true; + } else { + sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n"); + } + } + } + mWorkingNote.setWorkingText(sb.toString()); + } else { + mWorkingNote.setWorkingText(mNoteEditor.getText().toString()); + } + return hasChecked; + } + + private boolean saveNote() { + getWorkingText(); + boolean saved = mWorkingNote.saveNote(); + if (saved) { + /** + * There are two modes from List view to edit view, open one note, + * create/edit a node. Opening node requires to the original + * position in the list when back from edit view, while creating a + * new node requires to the top of the list. This code + * {@link #RESULT_OK} is used to identify the create/edit state + */ + setResult(RESULT_OK); + } + return saved; + } + + private void sendToDesktop() { + /** + * Before send message to home, we should make sure that current + * editing note is exists in databases. So, for new note, firstly + * save it + */ + if (!mWorkingNote.existInDatabase()) { + saveNote(); + } + + if (mWorkingNote.getNoteId() > 0) { + Intent sender = new Intent(); + Intent shortcutIntent = new Intent(this, NoteEditActivity.class); + shortcutIntent.setAction(Intent.ACTION_VIEW); + shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + sender.putExtra(Intent.EXTRA_SHORTCUT_NAME, + makeShortcutIconTitle(mWorkingNote.getContent())); + sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, + Intent.ShortcutIconResource.fromContext(this, R.drawable.icon_app)); + sender.putExtra("duplicate", true); + sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); + showToast(R.string.info_note_enter_desktop); + sendBroadcast(sender); + } else { + /** + * There is the condition that user has input nothing (the note is + * not worthy saving), we have no note id, remind the user that he + * should input something + */ + Log.e(TAG, "Send to desktop error"); + showToast(R.string.error_note_empty_for_send_to_desktop); + } + } + + private String makeShortcutIconTitle(String content) { + content = content.replace(TAG_CHECKED, ""); + content = content.replace(TAG_UNCHECKED, ""); + return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0, + SHORTCUT_ICON_TITLE_MAX_LEN) : content; + } + + private void showToast(int resId) { + showToast(resId, Toast.LENGTH_SHORT); + } + + private void showToast(int resId, int duration) { + Toast.makeText(this, resId, duration).show(); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditText.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditText.java new file mode 100644 index 0000000..2afe2a8 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteEditText.java @@ -0,0 +1,217 @@ +/* + * 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.graphics.Rect; +import android.text.Layout; +import android.text.Selection; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.style.URLSpan; +import android.util.AttributeSet; +import android.util.Log; +import android.view.ContextMenu; +import android.view.KeyEvent; +import android.view.MenuItem; +import android.view.MenuItem.OnMenuItemClickListener; +import android.view.MotionEvent; +import android.widget.EditText; + +import net.micode.notes.R; + +import java.util.HashMap; +import java.util.Map; + +public class NoteEditText extends EditText { + private static final String TAG = "NoteEditText"; + private int mIndex; + private int mSelectionStartBeforeDelete; + + private static final String SCHEME_TEL = "tel:" ; + private static final String SCHEME_HTTP = "http:" ; + private static final String SCHEME_EMAIL = "mailto:" ; + + private static final Map sSchemaActionResMap = new HashMap(); + static { + sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); + sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); + sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email); + } + + /** + * Call by the {@link NoteEditActivity} to delete or add edit text + */ + public interface OnTextViewChangeListener { + /** + * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens + * and the text is null + */ + void onEditTextDelete(int index, String text); + + /** + * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} + * happen + */ + void onEditTextEnter(int index, String text); + + /** + * Hide or show item option when text change + */ + void onTextChange(int index, boolean hasText); + } + + private OnTextViewChangeListener mOnTextViewChangeListener; + + public NoteEditText(Context context) { + super(context, null); + mIndex = 0; + } + + public void setIndex(int index) { + mIndex = index; + } + + public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { + mOnTextViewChangeListener = listener; + } + + public NoteEditText(Context context, AttributeSet attrs) { + super(context, attrs, android.R.attr.editTextStyle); + } + + public NoteEditText(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + // TODO Auto-generated constructor stub + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + + int x = (int) event.getX(); + int y = (int) event.getY(); + x -= getTotalPaddingLeft(); + y -= getTotalPaddingTop(); + x += getScrollX(); + y += getScrollY(); + + Layout layout = getLayout(); + int line = layout.getLineForVertical(y); + int off = layout.getOffsetForHorizontal(line, x); + Selection.setSelection(getText(), off); + break; + } + + return super.onTouchEvent(event); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + switch (keyCode) { + case KeyEvent.KEYCODE_ENTER: + if (mOnTextViewChangeListener != null) { + return false; + } + break; + case KeyEvent.KEYCODE_DEL: + mSelectionStartBeforeDelete = getSelectionStart(); + break; + default: + break; + } + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + switch(keyCode) { + case KeyEvent.KEYCODE_DEL: + if (mOnTextViewChangeListener != null) { + if (0 == mSelectionStartBeforeDelete && mIndex != 0) { + mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); + return true; + } + } else { + Log.d(TAG, "OnTextViewChangeListener was not seted"); + } + break; + case KeyEvent.KEYCODE_ENTER: + if (mOnTextViewChangeListener != null) { + int selectionStart = getSelectionStart(); + String text = getText().subSequence(selectionStart, length()).toString(); + setText(getText().subSequence(0, selectionStart)); + mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); + } else { + Log.d(TAG, "OnTextViewChangeListener was not seted"); + } + break; + default: + break; + } + return super.onKeyUp(keyCode, event); + } + + @Override + protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + if (mOnTextViewChangeListener != null) { + if (!focused && TextUtils.isEmpty(getText())) { + mOnTextViewChangeListener.onTextChange(mIndex, false); + } else { + mOnTextViewChangeListener.onTextChange(mIndex, true); + } + } + super.onFocusChanged(focused, direction, previouslyFocusedRect); + } + + @Override + protected void onCreateContextMenu(ContextMenu menu) { + if (getText() instanceof Spanned) { + int selStart = getSelectionStart(); + int selEnd = getSelectionEnd(); + + int min = Math.min(selStart, selEnd); + int max = Math.max(selStart, selEnd); + + final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); + if (urls.length == 1) { + int defaultResId = 0; + for(String schema: sSchemaActionResMap.keySet()) { + if(urls[0].getURL().indexOf(schema) >= 0) { + defaultResId = sSchemaActionResMap.get(schema); + break; + } + } + + if (defaultResId == 0) { + defaultResId = R.string.note_link_other; + } + + menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( + new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + // goto a new intent + urls[0].onClick(NoteEditText.this); + return true; + } + }); + } + } + super.onCreateContextMenu(menu); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteItemData.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteItemData.java new file mode 100644 index 0000000..0f5a878 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NoteItemData.java @@ -0,0 +1,224 @@ +/* + * 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.text.TextUtils; + +import net.micode.notes.data.Contact; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.tool.DataUtils; + + +public class NoteItemData { + static final String [] PROJECTION = new String [] { + NoteColumns.ID, + NoteColumns.ALERTED_DATE, + NoteColumns.BG_COLOR_ID, + NoteColumns.CREATED_DATE, + NoteColumns.HAS_ATTACHMENT, + NoteColumns.MODIFIED_DATE, + NoteColumns.NOTES_COUNT, + NoteColumns.PARENT_ID, + NoteColumns.SNIPPET, + NoteColumns.TYPE, + NoteColumns.WIDGET_ID, + NoteColumns.WIDGET_TYPE, + }; + + private static final int ID_COLUMN = 0; + private static final int ALERTED_DATE_COLUMN = 1; + private static final int BG_COLOR_ID_COLUMN = 2; + 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; + private static final int SNIPPET_COLUMN = 8; + private static final int TYPE_COLUMN = 9; + private static final int WIDGET_ID_COLUMN = 10; + private static final int WIDGET_TYPE_COLUMN = 11; + + private long mId; + private long mAlertDate; + private int mBgColorId; + private long mCreatedDate; + private boolean mHasAttachment; + private long mModifiedDate; + private int mNotesCount; + private long mParentId; + private String mSnippet; + private int mType; + private int mWidgetId; + 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); + mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN); + mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN); + 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); + 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); + mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN); + + mPhoneNumber = ""; + if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { + mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId); + if (!TextUtils.isEmpty(mPhoneNumber)) { + mName = Contact.getContact(context, mPhoneNumber); + if (mName == null) { + mName = mPhoneNumber; + } + } + } + + if (mName == null) { + mName = ""; + } + checkPostion(cursor); + } + + private void checkPostion(Cursor cursor) { + mIsLastItem = cursor.isLast() ? true : false; + mIsFirstItem = cursor.isFirst() ? true : false; + mIsOnlyOneItem = (cursor.getCount() == 1); + mIsMultiNotesFollowingFolder = false; + mIsOneNoteFollowingFolder = 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)) { + 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() { + return mId; + } + + public long getAlertDate() { + return mAlertDate; + } + + public long getCreatedDate() { + return mCreatedDate; + } + + public boolean hasAttachment() { + return mHasAttachment; + } + + public long getModifiedDate() { + return mModifiedDate; + } + + public int getBgColorId() { + return mBgColorId; + } + + public long getParentId() { + return mParentId; + } + + public int getNotesCount() { + return mNotesCount; + } + + public long getFolderId () { + return mParentId; + } + + public int getType() { + return mType; + } + + public int getWidgetType() { + return mWidgetType; + } + + public int getWidgetId() { + return mWidgetId; + } + + public String getSnippet() { + return mSnippet; + } + + public boolean hasAlert() { + return (mAlertDate > 0); + } + + public boolean isCallRecord() { + return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber)); + } + + public static int getNoteType(Cursor cursor) { + return cursor.getInt(TYPE_COLUMN); + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListActivity.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListActivity.java new file mode 100644 index 0000000..e843aec --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListActivity.java @@ -0,0 +1,954 @@ +/* + * 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.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.appwidget.AppWidgetManager; +import android.content.AsyncQueryHandler; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.Log; +import android.view.ActionMode; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.Display; +import android.view.HapticFeedbackConstants; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MenuItem.OnMenuItemClickListener; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnCreateContextMenuListener; +import android.view.View.OnTouchListener; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemLongClickListener; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.PopupMenu; +import android.widget.TextView; +import android.widget.Toast; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.remote.GTaskSyncService; +import net.micode.notes.model.WorkingNote; +import net.micode.notes.tool.BackupUtils; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.ResourceParser; +import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute; +import net.micode.notes.widget.NoteWidgetProvider_2x; +import net.micode.notes.widget.NoteWidgetProvider_4x; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashSet; + +public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { + private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; + + private static final int FOLDER_LIST_QUERY_TOKEN = 1; + + private static final int MENU_FOLDER_DELETE = 0; + + private static final int MENU_FOLDER_VIEW = 1; + + private static final int MENU_FOLDER_CHANGE_NAME = 2; + + private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; + + private enum ListEditState { + NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER + }; + + private ListEditState mState; + + private BackgroundQueryHandler mBackgroundQueryHandler; + + private NotesListAdapter mNotesListAdapter; + + private ListView mNotesListView; + + private Button mAddNewNote; + + private boolean mDispatch; + + private int mOriginY; + + private int mDispatchY; + + private TextView mTitleBar; + + private long mCurrentFolderId; + + private ContentResolver mContentResolver; + + private ModeCallback mModeCallBack; + + private static final String TAG = "NotesListActivity"; + + public static final int NOTES_LISTVIEW_SCROLL_RATE = 30; + + private NoteItemData mFocusNoteDataItem; + + private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; + + private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>" + + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" + " OR (" + + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + + NoteColumns.NOTES_COUNT + ">0)"; + + private final static int REQUEST_CODE_OPEN_NODE = 102; + private final static int REQUEST_CODE_NEW_NODE = 103; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.note_list); + initResources(); + + /** + * Insert an introduction when user firstly use this application + */ + setAppInfoFromRawRes(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == RESULT_OK + && (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE)) { + mNotesListAdapter.changeCursor(null); + } else { + super.onActivityResult(requestCode, resultCode, data); + } + } + + private void setAppInfoFromRawRes() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) { + StringBuilder sb = new StringBuilder(); + InputStream in = null; + try { + in = getResources().openRawResource(R.raw.introduction); + if (in != null) { + InputStreamReader isr = new InputStreamReader(in); + BufferedReader br = new BufferedReader(isr); + char [] buf = new char[1024]; + int len = 0; + while ((len = br.read(buf)) > 0) { + sb.append(buf, 0, len); + } + } else { + Log.e(TAG, "Read introduction file error"); + return; + } + } catch (IOException e) { + e.printStackTrace(); + return; + } finally { + if(in != null) { + try { + in.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + WorkingNote note = WorkingNote.createEmptyNote(this, Notes.ID_ROOT_FOLDER, + AppWidgetManager.INVALID_APPWIDGET_ID, Notes.TYPE_WIDGET_INVALIDE, + ResourceParser.RED); + note.setWorkingText(sb.toString()); + if (note.saveNote()) { + sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit(); + } else { + Log.e(TAG, "Save introduction note error"); + return; + } + } + } + + @Override + protected void onStart() { + super.onStart(); + startAsyncNotesListQuery(); + } + + private void initResources() { + mContentResolver = this.getContentResolver(); + mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver()); + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mNotesListView = (ListView) findViewById(R.id.notes_list); + mNotesListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.note_list_footer, null), + null, false); + mNotesListView.setOnItemClickListener(new OnListItemClickListener()); + mNotesListView.setOnItemLongClickListener(this); + mNotesListAdapter = new NotesListAdapter(this); + mNotesListView.setAdapter(mNotesListAdapter); + mAddNewNote = (Button) findViewById(R.id.btn_new_note); + mAddNewNote.setOnClickListener(this); + mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); + mDispatch = false; + mDispatchY = 0; + mOriginY = 0; + mTitleBar = (TextView) findViewById(R.id.tv_title_bar); + mState = ListEditState.NOTE_LIST; + mModeCallBack = new ModeCallback(); + } + + private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener { + private DropdownMenu mDropDownMenu; + private ActionMode mActionMode; + private MenuItem mMoveMenu; + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + getMenuInflater().inflate(R.menu.note_list_options, menu); + menu.findItem(R.id.delete).setOnMenuItemClickListener(this); + mMoveMenu = menu.findItem(R.id.move); + if (mFocusNoteDataItem.getParentId() == Notes.ID_CALL_RECORD_FOLDER + || DataUtils.getUserFolderCount(mContentResolver) == 0) { + mMoveMenu.setVisible(false); + } else { + mMoveMenu.setVisible(true); + mMoveMenu.setOnMenuItemClickListener(this); + } + mActionMode = mode; + mNotesListAdapter.setChoiceMode(true); + mNotesListView.setLongClickable(false); + mAddNewNote.setVisibility(View.GONE); + + View customView = LayoutInflater.from(NotesListActivity.this).inflate( + R.layout.note_list_dropdown_menu, null); + mode.setCustomView(customView); + mDropDownMenu = new DropdownMenu(NotesListActivity.this, + (Button) customView.findViewById(R.id.selection_menu), + R.menu.note_list_dropdown); + mDropDownMenu.setOnDropdownMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){ + public boolean onMenuItemClick(MenuItem item) { + mNotesListAdapter.selectAll(!mNotesListAdapter.isAllSelected()); + updateMenu(); + return true; + } + + }); + return true; + } + + private void updateMenu() { + int selectedCount = mNotesListAdapter.getSelectedCount(); + // Update dropdown menu + String format = getResources().getString(R.string.menu_select_title, selectedCount); + mDropDownMenu.setTitle(format); + MenuItem item = mDropDownMenu.findItem(R.id.action_select_all); + if (item != null) { + if (mNotesListAdapter.isAllSelected()) { + item.setChecked(true); + item.setTitle(R.string.menu_deselect_all); + } else { + item.setChecked(false); + item.setTitle(R.string.menu_select_all); + } + } + } + + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + // TODO Auto-generated method stub + return false; + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + // TODO Auto-generated method stub + return false; + } + + public void onDestroyActionMode(ActionMode mode) { + mNotesListAdapter.setChoiceMode(false); + mNotesListView.setLongClickable(true); + mAddNewNote.setVisibility(View.VISIBLE); + } + + public void finishActionMode() { + mActionMode.finish(); + } + + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, + boolean checked) { + mNotesListAdapter.setCheckedItem(position, checked); + updateMenu(); + } + + public boolean onMenuItemClick(MenuItem item) { + if (mNotesListAdapter.getSelectedCount() == 0) { + Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none), + Toast.LENGTH_SHORT).show(); + return true; + } + + switch (item.getItemId()) { + case R.id.delete: + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(getString(R.string.alert_title_delete)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_notes, + mNotesListAdapter.getSelectedCount())); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + batchDelete(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + break; + case R.id.move: + startQueryDestinationFolders(); + break; + default: + return false; + } + return true; + } + } + + private class NewNoteOnTouchListener implements OnTouchListener { + + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: { + Display display = getWindowManager().getDefaultDisplay(); + int screenHeight = display.getHeight(); + int newNoteViewHeight = mAddNewNote.getHeight(); + int start = screenHeight - newNoteViewHeight; + int eventY = start + (int) event.getY(); + /** + * Minus TitleBar's height + */ + if (mState == ListEditState.SUB_FOLDER) { + eventY -= mTitleBar.getHeight(); + start -= mTitleBar.getHeight(); + } + /** + * HACKME:When click the transparent part of "New Note" button, dispatch + * the event to the list view behind this button. The transparent part of + * "New Note" button could be expressed by formula y=-0.12x+94(Unit:pixel) + * and the line top of the button. The coordinate based on left of the "New + * Note" button. The 94 represents maximum height of the transparent part. + * Notice that, if the background of the button changes, the formula should + * also change. This is very bad, just for the UI designer's strong requirement. + */ + if (event.getY() < (event.getX() * (-0.12) + 94)) { + View view = mNotesListView.getChildAt(mNotesListView.getChildCount() - 1 + - mNotesListView.getFooterViewsCount()); + if (view != null && view.getBottom() > start + && (view.getTop() < (start + 94))) { + mOriginY = (int) event.getY(); + mDispatchY = eventY; + event.setLocation(event.getX(), mDispatchY); + mDispatch = true; + return mNotesListView.dispatchTouchEvent(event); + } + } + break; + } + case MotionEvent.ACTION_MOVE: { + if (mDispatch) { + mDispatchY += (int) event.getY() - mOriginY; + event.setLocation(event.getX(), mDispatchY); + return mNotesListView.dispatchTouchEvent(event); + } + break; + } + default: { + if (mDispatch) { + event.setLocation(event.getX(), mDispatchY); + mDispatch = false; + return mNotesListView.dispatchTouchEvent(event); + } + break; + } + } + return false; + } + + }; + + private void startAsyncNotesListQuery() { + String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION + : NORMAL_SELECTION; + mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null, + Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] { + String.valueOf(mCurrentFolderId) + }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); + } + + private final class BackgroundQueryHandler extends AsyncQueryHandler { + public BackgroundQueryHandler(ContentResolver contentResolver) { + super(contentResolver); + } + + @Override + protected void onQueryComplete(int token, Object cookie, Cursor cursor) { + switch (token) { + case FOLDER_NOTE_LIST_QUERY_TOKEN: + mNotesListAdapter.changeCursor(cursor); + break; + case FOLDER_LIST_QUERY_TOKEN: + if (cursor != null && cursor.getCount() > 0) { + showFolderListMenu(cursor); + } else { + Log.e(TAG, "Query folder failed"); + } + break; + default: + return; + } + } + } + + private void showFolderListMenu(Cursor cursor) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(R.string.menu_title_select_folder); + final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor); + builder.setAdapter(adapter, new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int which) { + DataUtils.batchMoveToFolder(mContentResolver, + mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which)); + Toast.makeText( + NotesListActivity.this, + getString(R.string.format_move_notes_to_folder, + mNotesListAdapter.getSelectedCount(), + adapter.getFolderName(NotesListActivity.this, which)), + Toast.LENGTH_SHORT).show(); + mModeCallBack.finishActionMode(); + } + }); + builder.show(); + } + + private void createNewNote() { + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_INSERT_OR_EDIT); + intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId); + this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); + } + + private void batchDelete() { + new AsyncTask>() { + protected HashSet doInBackground(Void... unused) { + HashSet widgets = mNotesListAdapter.getSelectedWidget(); + if (!isSyncMode()) { + // if not synced, delete notes directly + if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter + .getSelectedItemIds())) { + } else { + Log.e(TAG, "Delete notes error, should not happens"); + } + } else { + // in sync mode, we'll move the deleted note into the trash + // folder + if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter + .getSelectedItemIds(), Notes.ID_TRASH_FOLER)) { + Log.e(TAG, "Move notes to trash folder error, should not happens"); + } + } + return widgets; + } + + @Override + protected void onPostExecute(HashSet widgets) { + if (widgets != null) { + for (AppWidgetAttribute widget : widgets) { + if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID + && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { + updateWidget(widget.widgetId, widget.widgetType); + } + } + } + mModeCallBack.finishActionMode(); + } + }.execute(); + } + + private void deleteFolder(long folderId) { + if (folderId == Notes.ID_ROOT_FOLDER) { + Log.e(TAG, "Wrong folder id, should not happen " + folderId); + return; + } + + HashSet ids = new HashSet(); + ids.add(folderId); + HashSet widgets = DataUtils.getFolderNoteWidget(mContentResolver, + folderId); + if (!isSyncMode()) { + // if not synced, delete folder directly + DataUtils.batchDeleteNotes(mContentResolver, ids); + } else { + // in sync mode, we'll move the deleted folder into the trash folder + DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_TRASH_FOLER); + } + if (widgets != null) { + for (AppWidgetAttribute widget : widgets) { + if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID + && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { + updateWidget(widget.widgetId, widget.widgetType); + } + } + } + } + + private void openNode(NoteItemData data) { + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.putExtra(Intent.EXTRA_UID, data.getId()); + this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE); + } + + private void openFolder(NoteItemData data) { + mCurrentFolderId = data.getId(); + startAsyncNotesListQuery(); + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { + mState = ListEditState.CALL_RECORD_FOLDER; + mAddNewNote.setVisibility(View.GONE); + } else { + mState = ListEditState.SUB_FOLDER; + } + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { + mTitleBar.setText(R.string.call_record_folder_name); + } else { + mTitleBar.setText(data.getSnippet()); + } + mTitleBar.setVisibility(View.VISIBLE); + } + + public void onClick(View v) { + switch (v.getId()) { + case R.id.btn_new_note: + createNewNote(); + break; + default: + break; + } + } + + private void showSoftInput() { + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (inputMethodManager != null) { + inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + } + + private void hideSoftInput(View view) { + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + + private void showCreateOrModifyFolderDialog(final boolean create) { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null); + final EditText etName = (EditText) view.findViewById(R.id.et_foler_name); + showSoftInput(); + if (!create) { + if (mFocusNoteDataItem != null) { + etName.setText(mFocusNoteDataItem.getSnippet()); + builder.setTitle(getString(R.string.menu_folder_change_name)); + } else { + Log.e(TAG, "The long click data item is null"); + return; + } + } else { + etName.setText(""); + builder.setTitle(this.getString(R.string.menu_create_folder)); + } + + builder.setPositiveButton(android.R.string.ok, null); + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + hideSoftInput(etName); + } + }); + + final Dialog dialog = builder.setView(view).show(); + final Button positive = (Button)dialog.findViewById(android.R.id.button1); + positive.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + hideSoftInput(etName); + String name = etName.getText().toString(); + if (DataUtils.checkVisibleFolderName(mContentResolver, name)) { + Toast.makeText(NotesListActivity.this, getString(R.string.folder_exist, name), + Toast.LENGTH_LONG).show(); + etName.setSelection(0, etName.length()); + return; + } + if (!create) { + if (!TextUtils.isEmpty(name)) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.SNIPPET, name); + values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + values.put(NoteColumns.LOCAL_MODIFIED, 1); + mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID + + "=?", new String[] { + String.valueOf(mFocusNoteDataItem.getId()) + }); + } + } else if (!TextUtils.isEmpty(name)) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.SNIPPET, name); + values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + mContentResolver.insert(Notes.CONTENT_NOTE_URI, values); + } + dialog.dismiss(); + } + }); + + if (TextUtils.isEmpty(etName.getText())) { + positive.setEnabled(false); + } + /** + * When the name edit text is null, disable the positive button + */ + etName.addTextChangedListener(new TextWatcher() { + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // TODO Auto-generated method stub + + } + + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (TextUtils.isEmpty(etName.getText())) { + positive.setEnabled(false); + } else { + positive.setEnabled(true); + } + } + + public void afterTextChanged(Editable s) { + // TODO Auto-generated method stub + + } + }); + } + + @Override + public void onBackPressed() { + switch (mState) { + case SUB_FOLDER: + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mState = ListEditState.NOTE_LIST; + startAsyncNotesListQuery(); + mTitleBar.setVisibility(View.GONE); + break; + case CALL_RECORD_FOLDER: + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mState = ListEditState.NOTE_LIST; + mAddNewNote.setVisibility(View.VISIBLE); + mTitleBar.setVisibility(View.GONE); + startAsyncNotesListQuery(); + break; + case NOTE_LIST: + super.onBackPressed(); + break; + default: + break; + } + } + + private void updateWidget(int appWidgetId, int appWidgetType) { + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + if (appWidgetType == Notes.TYPE_WIDGET_2X) { + intent.setClass(this, NoteWidgetProvider_2x.class); + } else if (appWidgetType == Notes.TYPE_WIDGET_4X) { + intent.setClass(this, NoteWidgetProvider_4x.class); + } else { + Log.e(TAG, "Unspported widget type"); + return; + } + + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { + appWidgetId + }); + + sendBroadcast(intent); + setResult(RESULT_OK, intent); + } + + private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() { + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + if (mFocusNoteDataItem != null) { + menu.setHeaderTitle(mFocusNoteDataItem.getSnippet()); + menu.add(0, MENU_FOLDER_VIEW, 0, R.string.menu_folder_view); + menu.add(0, MENU_FOLDER_DELETE, 0, R.string.menu_folder_delete); + menu.add(0, MENU_FOLDER_CHANGE_NAME, 0, R.string.menu_folder_change_name); + } + } + }; + + @Override + public void onContextMenuClosed(Menu menu) { + if (mNotesListView != null) { + mNotesListView.setOnCreateContextMenuListener(null); + } + super.onContextMenuClosed(menu); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + if (mFocusNoteDataItem == null) { + Log.e(TAG, "The long click data item is null"); + return false; + } + switch (item.getItemId()) { + case MENU_FOLDER_VIEW: + openFolder(mFocusNoteDataItem); + break; + case MENU_FOLDER_DELETE: + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.alert_title_delete)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_folder)); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + deleteFolder(mFocusNoteDataItem.getId()); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + break; + case MENU_FOLDER_CHANGE_NAME: + showCreateOrModifyFolderDialog(false); + break; + default: + break; + } + + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + menu.clear(); + if (mState == ListEditState.NOTE_LIST) { + getMenuInflater().inflate(R.menu.note_list, menu); + // set sync or sync_cancel + menu.findItem(R.id.menu_sync).setTitle( + GTaskSyncService.isSyncing() ? R.string.menu_sync_cancel : R.string.menu_sync); + } else if (mState == ListEditState.SUB_FOLDER) { + getMenuInflater().inflate(R.menu.sub_folder, menu); + } else if (mState == ListEditState.CALL_RECORD_FOLDER) { + getMenuInflater().inflate(R.menu.call_record_folder, menu); + } else { + Log.e(TAG, "Wrong state:" + mState); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_new_folder: { + showCreateOrModifyFolderDialog(true); + break; + } + case R.id.menu_export_text: { + exportNoteToText(); + break; + } + case R.id.menu_sync: { + if (isSyncMode()) { + if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) { + GTaskSyncService.startSync(this); + } else { + GTaskSyncService.cancelSync(this); + } + } else { + startPreferenceActivity(); + } + break; + } + case R.id.menu_setting: { + startPreferenceActivity(); + break; + } + case R.id.menu_new_note: { + createNewNote(); + break; + } + case R.id.menu_search: + onSearchRequested(); + break; + default: + break; + } + return true; + } + + @Override + public boolean onSearchRequested() { + startSearch(null, false, null /* appData */, false); + return true; + } + + private void exportNoteToText() { + final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this); + new AsyncTask() { + + @Override + protected Integer doInBackground(Void... unused) { + return backup.exportToText(); + } + + @Override + protected void onPostExecute(Integer result) { + if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(NotesListActivity.this + .getString(R.string.failed_sdcard_export)); + builder.setMessage(NotesListActivity.this + .getString(R.string.error_sdcard_unmounted)); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } else if (result == BackupUtils.STATE_SUCCESS) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(NotesListActivity.this + .getString(R.string.success_sdcard_export)); + builder.setMessage(NotesListActivity.this.getString( + R.string.format_exported_file_location, backup + .getExportedTextFileName(), backup.getExportedTextFileDir())); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } else if (result == BackupUtils.STATE_SYSTEM_ERROR) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(NotesListActivity.this + .getString(R.string.failed_sdcard_export)); + builder.setMessage(NotesListActivity.this + .getString(R.string.error_sdcard_export)); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } + } + + }.execute(); + } + + private boolean isSyncMode() { + return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; + } + + private void startPreferenceActivity() { + Activity from = getParent() != null ? getParent() : this; + Intent intent = new Intent(from, NotesPreferenceActivity.class); + from.startActivityIfNeeded(intent, -1); + } + + private class OnListItemClickListener implements OnItemClickListener { + + public void onItemClick(AdapterView parent, View view, int position, long id) { + if (view instanceof NotesListItem) { + NoteItemData item = ((NotesListItem) view).getItemData(); + if (mNotesListAdapter.isInChoiceMode()) { + if (item.getType() == Notes.TYPE_NOTE) { + position = position - mNotesListView.getHeaderViewsCount(); + mModeCallBack.onItemCheckedStateChanged(null, position, id, + !mNotesListAdapter.isSelectedItem(position)); + } + return; + } + + switch (mState) { + case NOTE_LIST: + if (item.getType() == Notes.TYPE_FOLDER + || item.getType() == Notes.TYPE_SYSTEM) { + openFolder(item); + } else if (item.getType() == Notes.TYPE_NOTE) { + openNode(item); + } else { + Log.e(TAG, "Wrong note type in NOTE_LIST"); + } + break; + case SUB_FOLDER: + case CALL_RECORD_FOLDER: + if (item.getType() == Notes.TYPE_NOTE) { + openNode(item); + } else { + Log.e(TAG, "Wrong note type in SUB_FOLDER"); + } + break; + default: + break; + } + } + } + + } + + private void startQueryDestinationFolders() { + String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?"; + selection = (mState == ListEditState.NOTE_LIST) ? selection: + "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")"; + + mBackgroundQueryHandler.startQuery(FOLDER_LIST_QUERY_TOKEN, + null, + Notes.CONTENT_NOTE_URI, + FoldersListAdapter.PROJECTION, + selection, + new String[] { + String.valueOf(Notes.TYPE_FOLDER), + String.valueOf(Notes.ID_TRASH_FOLER), + String.valueOf(mCurrentFolderId) + }, + NoteColumns.MODIFIED_DATE + " DESC"); + } + + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + if (view instanceof NotesListItem) { + mFocusNoteDataItem = ((NotesListItem) view).getItemData(); + if (mFocusNoteDataItem.getType() == Notes.TYPE_NOTE && !mNotesListAdapter.isInChoiceMode()) { + if (mNotesListView.startActionMode(mModeCallBack) != null) { + mModeCallBack.onItemCheckedStateChanged(null, position, id, true); + mNotesListView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } else { + Log.e(TAG, "startActionMode fails"); + } + } else if (mFocusNoteDataItem.getType() == Notes.TYPE_FOLDER) { + mNotesListView.setOnCreateContextMenuListener(mFolderOnCreateContextMenuListener); + } + } + return false; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListAdapter.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListAdapter.java new file mode 100644 index 0000000..51c9cb9 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/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; + +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 { + private static final String TAG = "NotesListAdapter"; + private Context mContext; + private HashMap mSelectedIndex; + private int mNotesCount; + private boolean mChoiceMode; + + public static class AppWidgetAttribute { + 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) { + 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() { + 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"); + 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() { + 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) { + if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) { + mNotesCount++; + } + } else { + Log.e(TAG, "Invalid cursor"); + return; + } + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListItem.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListItem.java new file mode 100644 index 0000000..1221e80 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesListItem.java @@ -0,0 +1,122 @@ +/* + * 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.text.format.DateUtils; +import android.view.View; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.ResourceParser.NoteItemBgResources; + + +public class NotesListItem extends LinearLayout { + private ImageView mAlert; + private TextView mTitle; + private TextView mTime; + private TextView mCallName; + private NoteItemData mItemData; + private CheckBox mCheckBox; + + public NotesListItem(Context context) { + super(context); + inflate(context, R.layout.note_item, this); + mAlert = (ImageView) findViewById(R.id.iv_alert_icon); + mTitle = (TextView) findViewById(R.id.tv_title); + mTime = (TextView) findViewById(R.id.tv_time); + mCallName = (TextView) findViewById(R.id.tv_name); + mCheckBox = (CheckBox) findViewById(android.R.id.checkbox); + } + + public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) { + if (choiceMode && data.getType() == Notes.TYPE_NOTE) { + mCheckBox.setVisibility(View.VISIBLE); + mCheckBox.setChecked(checked); + } else { + mCheckBox.setVisibility(View.GONE); + } + + mItemData = data; + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { + mCallName.setVisibility(View.GONE); + mAlert.setVisibility(View.VISIBLE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); + mTitle.setText(context.getString(R.string.call_record_folder_name) + + context.getString(R.string.format_folder_files_count, data.getNotesCount())); + mAlert.setImageResource(R.drawable.call_record); + } else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) { + mCallName.setVisibility(View.VISIBLE); + mCallName.setText(data.getCallName()); + mTitle.setTextAppearance(context,R.style.TextAppearanceSecondaryItem); + mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); + if (data.hasAlert()) { + mAlert.setImageResource(R.drawable.clock); + mAlert.setVisibility(View.VISIBLE); + } else { + mAlert.setVisibility(View.GONE); + } + } else { + mCallName.setVisibility(View.GONE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); + + if (data.getType() == Notes.TYPE_FOLDER) { + mTitle.setText(data.getSnippet() + + context.getString(R.string.format_folder_files_count, + data.getNotesCount())); + mAlert.setVisibility(View.GONE); + } else { + mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); + if (data.hasAlert()) { + mAlert.setImageResource(R.drawable.clock); + mAlert.setVisibility(View.VISIBLE); + } else { + mAlert.setVisibility(View.GONE); + } + } + } + mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate())); + + setBackground(data); + } + + private void setBackground(NoteItemData data) { + int id = data.getBgColorId(); + if (data.getType() == Notes.TYPE_NOTE) { + if (data.isSingle() || data.isOneFollowingFolder()) { + setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id)); + } else if (data.isLast()) { + setBackgroundResource(NoteItemBgResources.getNoteBgLastRes(id)); + } else if (data.isFirst() || data.isMultiFollowingFolder()) { + setBackgroundResource(NoteItemBgResources.getNoteBgFirstRes(id)); + } else { + setBackgroundResource(NoteItemBgResources.getNoteBgNormalRes(id)); + } + } else { + setBackgroundResource(NoteItemBgResources.getFolderBgRes()); + } + } + + public NoteItemData getItemData() { + return mItemData; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesPreferenceActivity.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesPreferenceActivity.java new file mode 100644 index 0000000..07c5f7e --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/ui/NotesPreferenceActivity.java @@ -0,0 +1,388 @@ +/* + * 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.accounts.Account; +import android.accounts.AccountManager; +import android.app.ActionBar; +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceActivity; +import android.preference.PreferenceCategory; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.remote.GTaskSyncService; + + +public class NotesPreferenceActivity extends PreferenceActivity { + public static final String PREFERENCE_NAME = "notes_preferences"; + + public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name"; + + public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time"; + + public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear"; + + private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key"; + + private static final String AUTHORITIES_FILTER_KEY = "authorities"; + + private PreferenceCategory mAccountCategory; + + private GTaskReceiver mReceiver; + + private Account[] mOriAccounts; + + private boolean mHasAddedAccount; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + + /* using the app icon for navigation */ + getActionBar().setDisplayHomeAsUpEnabled(true); + + addPreferencesFromResource(R.xml.preferences); + mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY); + mReceiver = new GTaskReceiver(); + IntentFilter filter = new IntentFilter(); + filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME); + registerReceiver(mReceiver, filter); + + mOriAccounts = null; + View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null); + getListView().addHeaderView(header, null, true); + } + + @Override + protected void onResume() { + super.onResume(); + + // need to set sync account automatically if user has added a new + // account + if (mHasAddedAccount) { + Account[] accounts = getGoogleAccounts(); + if (mOriAccounts != null && accounts.length > mOriAccounts.length) { + for (Account accountNew : accounts) { + boolean found = false; + for (Account accountOld : mOriAccounts) { + if (TextUtils.equals(accountOld.name, accountNew.name)) { + found = true; + break; + } + } + if (!found) { + setSyncAccount(accountNew.name); + break; + } + } + } + } + + refreshUI(); + } + + @Override + protected void onDestroy() { + if (mReceiver != null) { + unregisterReceiver(mReceiver); + } + super.onDestroy(); + } + + private void loadAccountPreference() { + mAccountCategory.removeAll(); + + Preference accountPref = new Preference(this); + final String defaultAccount = getSyncAccountName(this); + accountPref.setTitle(getString(R.string.preferences_account_title)); + accountPref.setSummary(getString(R.string.preferences_account_summary)); + accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + if (!GTaskSyncService.isSyncing()) { + if (TextUtils.isEmpty(defaultAccount)) { + // the first time to set account + showSelectAccountAlertDialog(); + } else { + // if the account has already been set, we need to promp + // user about the risk + showChangeAccountConfirmAlertDialog(); + } + } else { + Toast.makeText(NotesPreferenceActivity.this, + R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT) + .show(); + } + return true; + } + }); + + mAccountCategory.addPreference(accountPref); + } + + private void loadSyncButton() { + Button syncButton = (Button) findViewById(R.id.preference_sync_button); + TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview); + + // set button state + if (GTaskSyncService.isSyncing()) { + syncButton.setText(getString(R.string.preferences_button_sync_cancel)); + syncButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + GTaskSyncService.cancelSync(NotesPreferenceActivity.this); + } + }); + } else { + syncButton.setText(getString(R.string.preferences_button_sync_immediately)); + syncButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + GTaskSyncService.startSync(NotesPreferenceActivity.this); + } + }); + } + syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this))); + + // set last sync time + if (GTaskSyncService.isSyncing()) { + lastSyncTimeView.setText(GTaskSyncService.getProgressString()); + lastSyncTimeView.setVisibility(View.VISIBLE); + } else { + long lastSyncTime = getLastSyncTime(this); + if (lastSyncTime != 0) { + lastSyncTimeView.setText(getString(R.string.preferences_last_sync_time, + DateFormat.format(getString(R.string.preferences_last_sync_time_format), + lastSyncTime))); + lastSyncTimeView.setVisibility(View.VISIBLE); + } else { + lastSyncTimeView.setVisibility(View.GONE); + } + } + } + + private void refreshUI() { + loadAccountPreference(); + loadSyncButton(); + } + + private void showSelectAccountAlertDialog() { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); + + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); + TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); + titleTextView.setText(getString(R.string.preferences_dialog_select_account_title)); + TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); + subtitleTextView.setText(getString(R.string.preferences_dialog_select_account_tips)); + + dialogBuilder.setCustomTitle(titleView); + dialogBuilder.setPositiveButton(null, null); + + Account[] accounts = getGoogleAccounts(); + String defAccount = getSyncAccountName(this); + + mOriAccounts = accounts; + mHasAddedAccount = false; + + if (accounts.length > 0) { + CharSequence[] items = new CharSequence[accounts.length]; + final CharSequence[] itemMapping = items; + int checkedItem = -1; + int index = 0; + for (Account account : accounts) { + if (TextUtils.equals(account.name, defAccount)) { + checkedItem = index; + } + items[index++] = account.name; + } + dialogBuilder.setSingleChoiceItems(items, checkedItem, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + setSyncAccount(itemMapping[which].toString()); + dialog.dismiss(); + refreshUI(); + } + }); + } + + View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null); + dialogBuilder.setView(addAccountView); + + final AlertDialog dialog = dialogBuilder.show(); + addAccountView.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + mHasAddedAccount = true; + Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS"); + intent.putExtra(AUTHORITIES_FILTER_KEY, new String[] { + "gmail-ls" + }); + startActivityForResult(intent, -1); + dialog.dismiss(); + } + }); + } + + private void showChangeAccountConfirmAlertDialog() { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); + + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); + TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); + titleTextView.setText(getString(R.string.preferences_dialog_change_account_title, + getSyncAccountName(this))); + TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); + subtitleTextView.setText(getString(R.string.preferences_dialog_change_account_warn_msg)); + dialogBuilder.setCustomTitle(titleView); + + CharSequence[] menuItemArray = new CharSequence[] { + getString(R.string.preferences_menu_change_account), + getString(R.string.preferences_menu_remove_account), + getString(R.string.preferences_menu_cancel) + }; + dialogBuilder.setItems(menuItemArray, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + if (which == 0) { + showSelectAccountAlertDialog(); + } else if (which == 1) { + removeSyncAccount(); + refreshUI(); + } + } + }); + dialogBuilder.show(); + } + + private Account[] getGoogleAccounts() { + AccountManager accountManager = AccountManager.get(this); + return accountManager.getAccountsByType("com.google"); + } + + private void setSyncAccount(String account) { + if (!getSyncAccountName(this).equals(account)) { + SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = settings.edit(); + if (account != null) { + editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, account); + } else { + editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); + } + editor.commit(); + + // clean up last sync time + setLastSyncTime(this, 0); + + // clean up local gtask related info + new Thread(new Runnable() { + public void run() { + ContentValues values = new ContentValues(); + values.put(NoteColumns.GTASK_ID, ""); + values.put(NoteColumns.SYNC_ID, 0); + getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); + } + }).start(); + + Toast.makeText(NotesPreferenceActivity.this, + getString(R.string.preferences_toast_success_set_accout, account), + Toast.LENGTH_SHORT).show(); + } + } + + private void removeSyncAccount() { + SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = settings.edit(); + if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) { + editor.remove(PREFERENCE_SYNC_ACCOUNT_NAME); + } + if (settings.contains(PREFERENCE_LAST_SYNC_TIME)) { + editor.remove(PREFERENCE_LAST_SYNC_TIME); + } + editor.commit(); + + // clean up local gtask related info + new Thread(new Runnable() { + public void run() { + ContentValues values = new ContentValues(); + values.put(NoteColumns.GTASK_ID, ""); + values.put(NoteColumns.SYNC_ID, 0); + getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); + } + }).start(); + } + + public static String getSyncAccountName(Context context) { + SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, + Context.MODE_PRIVATE); + return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); + } + + public static void setLastSyncTime(Context context, long time) { + SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = settings.edit(); + editor.putLong(PREFERENCE_LAST_SYNC_TIME, time); + editor.commit(); + } + + public static long getLastSyncTime(Context context) { + SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, + Context.MODE_PRIVATE); + return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0); + } + + private class GTaskReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + refreshUI(); + if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) { + TextView syncStatus = (TextView) findViewById(R.id.prefenerece_sync_status_textview); + syncStatus.setText(intent + .getStringExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG)); + } + + } + } + + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + Intent intent = new Intent(this, NotesListActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + return true; + default: + return false; + } + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider.java new file mode 100644 index 0000000..ec6f819 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider.java @@ -0,0 +1,132 @@ +/* + * 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.widget; +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.util.Log; +import android.widget.RemoteViews; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.tool.ResourceParser; +import net.micode.notes.ui.NoteEditActivity; +import net.micode.notes.ui.NotesListActivity; + +public abstract class NoteWidgetProvider extends AppWidgetProvider { + public static final String [] PROJECTION = new String [] { + NoteColumns.ID, + NoteColumns.BG_COLOR_ID, + NoteColumns.SNIPPET + }; + + public static final int COLUMN_ID = 0; + public static final int COLUMN_BG_COLOR_ID = 1; + public static final int COLUMN_SNIPPET = 2; + + private static final String TAG = "NoteWidgetProvider"; + + @Override + public void onDeleted(Context context, int[] appWidgetIds) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + for (int i = 0; i < appWidgetIds.length; i++) { + context.getContentResolver().update(Notes.CONTENT_NOTE_URI, + values, + NoteColumns.WIDGET_ID + "=?", + new String[] { String.valueOf(appWidgetIds[i])}); + } + } + + private Cursor getNoteWidgetInfo(Context context, int widgetId) { + return context.getContentResolver().query(Notes.CONTENT_NOTE_URI, + PROJECTION, + NoteColumns.WIDGET_ID + "=? AND " + NoteColumns.PARENT_ID + "<>?", + new String[] { String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER) }, + null); + } + + protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + update(context, appWidgetManager, appWidgetIds, false); + } + + private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds, + boolean privacyMode) { + for (int i = 0; i < appWidgetIds.length; i++) { + if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) { + int bgId = ResourceParser.getDefaultBgId(context); + String snippet = ""; + Intent intent = new Intent(context, NoteEditActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetIds[i]); + intent.putExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, getWidgetType()); + + Cursor c = getNoteWidgetInfo(context, appWidgetIds[i]); + if (c != null && c.moveToFirst()) { + if (c.getCount() > 1) { + Log.e(TAG, "Multiple message with same widget id:" + appWidgetIds[i]); + c.close(); + return; + } + snippet = c.getString(COLUMN_SNIPPET); + bgId = c.getInt(COLUMN_BG_COLOR_ID); + intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_ID)); + intent.setAction(Intent.ACTION_VIEW); + } else { + snippet = context.getResources().getString(R.string.widget_havenot_content); + intent.setAction(Intent.ACTION_INSERT_OR_EDIT); + } + + if (c != null) { + c.close(); + } + + RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId()); + rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId)); + intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId); + /** + * Generate the pending intent to start host for the widget + */ + PendingIntent pendingIntent = null; + if (privacyMode) { + rv.setTextViewText(R.id.widget_text, + context.getString(R.string.widget_under_visit_mode)); + pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], new Intent( + context, NotesListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); + } else { + rv.setTextViewText(R.id.widget_text, snippet); + pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent, + PendingIntent.FLAG_UPDATE_CURRENT); + } + + rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent); + appWidgetManager.updateAppWidget(appWidgetIds[i], rv); + } + } + } + + protected abstract int getBgResourceId(int bgId); + + protected abstract int getLayoutId(); + + protected abstract int getWidgetType(); +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_2x.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_2x.java new file mode 100644 index 0000000..adcb2f7 --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_2x.java @@ -0,0 +1,47 @@ +/* + * 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.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.ResourceParser; + + +public class NoteWidgetProvider_2x extends NoteWidgetProvider { + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + super.update(context, appWidgetManager, appWidgetIds); + } + + @Override + protected int getLayoutId() { + return R.layout.widget_2x; + } + + @Override + protected int getBgResourceId(int bgId) { + return ResourceParser.WidgetBgResources.getWidget2xBgResource(bgId); + } + + @Override + protected int getWidgetType() { + return Notes.TYPE_WIDGET_2X; + } +} diff --git a/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_4x.java b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_4x.java new file mode 100644 index 0000000..c12a02e --- /dev/null +++ b/src/Notesmaster/app/src/androidTest/java/net/micode/notes/widget/NoteWidgetProvider_4x.java @@ -0,0 +1,46 @@ +/* + * 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.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.ResourceParser; + + +public class NoteWidgetProvider_4x extends NoteWidgetProvider { + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + super.update(context, appWidgetManager, appWidgetIds); + } + + protected int getLayoutId() { + return R.layout.widget_4x; + } + + @Override + protected int getBgResourceId(int bgId) { + return ResourceParser.WidgetBgResources.getWidget4xBgResource(bgId); + } + + @Override + protected int getWidgetType() { + return Notes.TYPE_WIDGET_4X; + } +} diff --git a/src/Notesmaster/app/src/main/AndroidManifest.xml b/src/Notesmaster/app/src/main/AndroidManifest.xml index e061ed5..9326ccb 100644 --- a/src/Notesmaster/app/src/main/AndroidManifest.xml +++ b/src/Notesmaster/app/src/main/AndroidManifest.xml @@ -2,16 +2,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java index a1deb99..3d030f8 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java @@ -63,25 +63,43 @@ public class GTaskASyncTask extends AsyncTask { }); } - private void showNotification(int tickerId, String content) { - PendingIntent pendingIntent; - if (tickerId != R.string.ticker_success) { - pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, - NotesPreferenceActivity.class), PendingIntent.FLAG_IMMUTABLE); - } else { - pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, - NotesListActivity.class), PendingIntent.FLAG_IMMUTABLE); - } - Notification.Builder builder = new Notification.Builder(mContext) - .setAutoCancel(true) - .setContentTitle(mContext.getString(R.string.app_name)) - .setContentText(content) - .setContentIntent(pendingIntent) - .setWhen(System.currentTimeMillis()) - .setOngoing(true); - Notification notification=builder.getNotification(); - mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification); +// private void showNotification(int tickerId, String content) { +// Notification notification = new Notification(R.drawable.notification, mContext +// .getString(tickerId), System.currentTimeMillis()); +// notification.defaults = Notification.DEFAULT_LIGHTS; +// notification.flags = Notification.FLAG_AUTO_CANCEL; +// PendingIntent pendingIntent; +// if (tickerId != R.string.ticker_success) { +//pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, +// NotesPreferenceActivity.class), 0); +// +// } else { +// pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, +// NotesListActivity.class), 0); +// } +// notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content, +// pendingIntent); + // mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification); + // } +private void showNotification(int tickerId, String content) { + PendingIntent pendingIntent; + if (tickerId != R.string.ticker_success) { + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + NotesPreferenceActivity.class), PendingIntent.FLAG_IMMUTABLE); + } else { + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + NotesListActivity.class), PendingIntent.FLAG_IMMUTABLE); } + Notification.Builder builder = new Notification.Builder(mContext) + .setAutoCancel(true) + .setContentTitle(mContext.getString(R.string.app_name)) + .setContentText(content) + .setContentIntent(pendingIntent) + .setWhen(System.currentTimeMillis()) + .setOngoing(true); + Notification notification=builder.getNotification(); + +} @Override protected Integer doInBackground(Void... unused) { diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java index 8f11e38..85723be 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java @@ -39,81 +39,58 @@ import net.micode.notes.tool.DataUtils; import java.io.IOException; + public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { - private long mNoteId; //文本在数据库存储中的ID号 - private String mSnippet; //闹钟提示时出现的文本片段 + private long mNoteId; + private String mSnippet; private static final int SNIPPET_PREW_MAX_LEN = 60; MediaPlayer mPlayer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - //Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的 - //onsaveInstanceState方法是用来保存Activity的状态的 - //能从onCreate的参数savedInsanceState中获得状态数据 requestWindowFeature(Window.FEATURE_NO_TITLE); - //界面显示——无标题 final Window win = getWindow(); win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); if (!isScreenOn()) { win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON - //保持窗体点亮 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON - //将窗体点亮 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON - //允许窗体点亮时锁屏 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); - }//在手机锁屏后如果到了闹钟提示时间,点亮屏幕 + } Intent intent = getIntent(); try { mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); - //根据ID从数据库中获取标签的内容; - //getContentResolver()是实现数据共享,实例存储。 mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) : mSnippet; - //判断标签片段是否达到符合长度 } catch (IllegalArgumentException e) { e.printStackTrace(); return; } - /* - try - { - // 代码区 - } - catch(Exception e) - { - // 异常处理 - } - 代码区如果有错误,就会返回所写异常的处理。*/ + mPlayer = new MediaPlayer(); if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { showActionDialog(); - //弹出对话框 playAlarmSound(); - //闹钟提示音激发 } else { finish(); - //完成闹钟动作 } } private boolean isScreenOn() { - //判断屏幕是否锁屏,调用系统函数判断,最后返回值是布尔类型 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); return pm.isScreenOn(); } private void playAlarmSound() { - //闹钟提示音激发 Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); - //调用系统的铃声管理URI,得到闹钟提示音 + int silentModeStreams = Settings.System.getInt(getContentResolver(), Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); @@ -124,19 +101,12 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD } try { mPlayer.setDataSource(this, url); - //方法:setDataSource(Context context, Uri uri) - //解释:无返回值,设置多媒体数据来源【根据 Uri】 mPlayer.prepare(); - //准备同步 mPlayer.setLooping(true); - //设置是否循环播放 mPlayer.start(); - //开始播放 } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); - //e.printStackTrace()函数功能是抛出异常, 还将显示出更深的调用信息 - //System.out.println(e),这个方法打印出异常,并且输出在哪里出现的异常 } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -151,58 +121,38 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD private void showActionDialog() { AlertDialog.Builder dialog = new AlertDialog.Builder(this); - //AlertDialog的构造方法全部是Protected的 - //所以不能直接通过new一个AlertDialog来创建出一个AlertDialog。 - //要创建一个AlertDialog,就要用到AlertDialog.Builder中的create()方法 - //如这里的dialog就是新建了一个AlertDialog dialog.setTitle(R.string.app_name); - //为对话框设置标题 dialog.setMessage(mSnippet); - //为对话框设置内容 dialog.setPositiveButton(R.string.notealert_ok, this); - //给对话框添加"Yes"按钮 if (isScreenOn()) { dialog.setNegativeButton(R.string.notealert_enter, this); - }//对话框添加"No"按钮 + } dialog.show().setOnDismissListener(this); } public void onClick(DialogInterface dialog, int which) { switch (which) { - //用which来选择click后下一步的操作 case DialogInterface.BUTTON_NEGATIVE: - //这是取消操作 Intent intent = new Intent(this, NoteEditActivity.class); - //实现两个类间的数据传输 intent.setAction(Intent.ACTION_VIEW); - //设置动作属性 intent.putExtra(Intent.EXTRA_UID, mNoteId); - //实现key-value对 - //EXTRA_UID为key;mNoteId为键 startActivity(intent); - //开始动作 break; default: - //这是确定操作 break; } } public void onDismiss(DialogInterface dialog) { - //忽略 stopAlarmSound(); - //停止闹钟声音 finish(); - //完成该动作 } private void stopAlarmSound() { if (mPlayer != null) { mPlayer.stop(); - //停止播放 mPlayer.release(); - //释放MediaPlayer对象 mPlayer = null; } } -} \ No newline at end of file +} diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java index f1c1c37..f221202 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.micode.notes.ui; import android.app.AlarmManager; @@ -30,25 +31,21 @@ import net.micode.notes.data.Notes.NoteColumns; public class AlarmInitReceiver extends BroadcastReceiver { private static final String [] PROJECTION = new String [] { - NoteColumns.ID, - NoteColumns.ALERTED_DATE + NoteColumns.ID, + NoteColumns.ALERTED_DATE }; - //对数据库的操作,调用标签ID和闹钟时间 + private static final int COLUMN_ID = 0; private static final int COLUMN_ALERTED_DATE = 1; @Override public void onReceive(Context context, Intent intent) { long currentDate = System.currentTimeMillis(); - //System.currentTimeMillis()产生一个当前的毫秒 - //这个毫秒其实就是自1970年1月1日0时起的毫秒数 Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, PROJECTION, NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, new String[] { String.valueOf(currentDate) }, - //将long变量currentDate转化为字符串 null); - //Cursor在这里的作用是通过查找数据库中的标签内容,找到和当前系统时间相等的标签 if (c != null) { if (c.moveToFirst()) { @@ -64,8 +61,5 @@ public class AlarmInitReceiver extends BroadcastReceiver { } c.close(); } - //然而通过网上查找资料发现,对于闹钟机制的启动,通常需要上面的几个步骤 - //如新建Intent、PendingIntent以及AlarmManager等 - //这里就是根据数据库里的闹钟时间创建一个闹钟机制 } -} \ No newline at end of file +} diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java index 7c5a0b1..54e503b 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.micode.notes.ui; import android.content.BroadcastReceiver; @@ -23,12 +24,7 @@ public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { intent.setClass(context, AlarmAlertActivity.class); - //启动AlarmAlertActivity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - //activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈 - //所以要新起一个栈装入启动的activity context.startActivity(intent); } } -//这是实现alarm这个功能最接近用户层的包,基于上面的两个包, -//作用还需要深究但是对于setClass和addFlags的 diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DateTimePicker.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DateTimePicker.java index 4e14d68..496b0cd 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DateTimePicker.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DateTimePicker.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.micode.notes.ui; import java.text.DateFormatSymbols; @@ -28,8 +29,7 @@ import android.widget.FrameLayout; import android.widget.NumberPicker; public class DateTimePicker extends FrameLayout { - //FrameLayout是布局模板之一 - //所有的子元素全部在屏幕的右上方 + private static final boolean DEFAULT_ENABLE_STATE = true; private static final int HOURS_IN_HALF_DAY = 12; @@ -45,15 +45,13 @@ public class DateTimePicker extends FrameLayout { private static final int MINUT_SPINNER_MAX_VAL = 59; private static final int AMPM_SPINNER_MIN_VAL = 0; private static final int AMPM_SPINNER_MAX_VAL = 1; - //初始化控件 + private final NumberPicker mDateSpinner; private final NumberPicker mHourSpinner; private final NumberPicker mMinuteSpinner; private final NumberPicker mAmPmSpinner; - //NumberPicker是数字选择器 - //这里定义的四个变量全部是在设置闹钟时需要选择的变量(如日期、时、分、上午或者下午) private Calendar mDate; - //定义了Calendar类型的变量mDate,用于操作时间 + private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; private boolean mIsAm; @@ -73,49 +71,41 @@ public class DateTimePicker extends FrameLayout { updateDateControl(); onDateTimeChanged(); } - };//OnValueChangeListener,这是时间改变监听器,这里主要是对日期的监听 - //将现在日期的值传递给mDate;updateDateControl是同步操作 + }; private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { - //这里是对 小时(Hour) 的监听 @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { boolean isDateChanged = false; Calendar cal = Calendar.getInstance(); - //声明一个Calendar的变量cal,便于后续的操作 if (!mIs24HourView) { if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; - //这里是对于12小时制时,晚上11点和12点交替时对日期的更改 } else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; } - //这里是对于12小时制时,凌晨11点和12点交替时对日期的更改 if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { mIsAm = !mIsAm; updateAmPmControl(); - }//这里是对于12小时制时,中午11点和12点交替时对AM和PM的更改 + } } else { if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; - //这里是对于24小时制时,晚上11点和12点交替时对日期的更改 } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; } - } //这里是对于12小时制时,凌晨11点和12点交替时对日期的更改 + } int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); - //通过数字选择器对newHour的赋值 mDate.set(Calendar.HOUR_OF_DAY, newHour); - //通过set函数将新的Hour值传给mDate onDateTimeChanged(); if (isDateChanged) { setCurrentYear(cal.get(Calendar.YEAR)); @@ -127,19 +117,15 @@ public class DateTimePicker extends FrameLayout { private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { @Override - //这里是对 分钟(Minute)改变的监听 public void onValueChange(NumberPicker picker, int oldVal, int newVal) { int minValue = mMinuteSpinner.getMinValue(); int maxValue = mMinuteSpinner.getMaxValue(); int offset = 0; - //设置offset,作为小时改变的一个记录数据 if (oldVal == maxValue && newVal == minValue) { offset += 1; } else if (oldVal == minValue && newVal == maxValue) { offset -= 1; } - //如果原值为59,新值为0,则offset加1 - //如果原值为0,新值为59,则offset减1 if (offset != 0) { mDate.add(Calendar.HOUR_OF_DAY, offset); mHourSpinner.setValue(getCurrentHour()); @@ -159,7 +145,6 @@ public class DateTimePicker extends FrameLayout { }; private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { - //对AM和PM的监听 @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mIsAm = !mIsAm; @@ -175,27 +160,24 @@ public class DateTimePicker extends FrameLayout { public interface OnDateTimeChangedListener { void onDateTimeChanged(DateTimePicker view, int year, int month, - int dayOfMonth, int hourOfDay, int minute); + int dayOfMonth, int hourOfDay, int minute); } public DateTimePicker(Context context) { this(context, System.currentTimeMillis()); - }//通过对数据库的访问,获取当前的系统时间 + } public DateTimePicker(Context context, long date) { this(context, date, DateFormat.is24HourFormat(context)); - }//上面函数的得到的是一个天文数字(1970至今的秒数),需要DateFormat将其变得有意义 + } public DateTimePicker(Context context, long date, boolean is24HourView) { super(context); - //获取系统时间 mDate = Calendar.getInstance(); mInitialising = true; mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; inflate(context, R.layout.datetime_picker, this); - //如果当前Activity里用到别的layout,比如对话框layout - //还要设置这个layout上的其他组件的内容,就必须用inflate()方法先将对话框的layout找出来 - //然后再用findViewById()找到它上面的其它组件 + mDateSpinner = (NumberPicker) findViewById(R.id.date); mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); @@ -203,7 +185,7 @@ public class DateTimePicker extends FrameLayout { mHourSpinner = (NumberPicker) findViewById(R.id.hour); mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); - mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); + mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); mMinuteSpinner.setOnLongPressUpdateInterval(100); @@ -244,9 +226,7 @@ public class DateTimePicker extends FrameLayout { mAmPmSpinner.setEnabled(enabled); mIsEnabled = enabled; } - //存在疑问!!!!!!!!!!!!!setEnabled的作用 - //下面的代码通过原程序的注释已经比较清晰,另外可以通过函数名来判断 - //下面的各函数主要是对上面代码引用到的各函数功能的实现 + @Override public boolean isEnabled() { return mIsEnabled; @@ -259,7 +239,7 @@ public class DateTimePicker extends FrameLayout { */ public long getCurrentDateInTimeMillis() { return mDate.getTimeInMillis(); - }//实现函数——得到当前的秒数 + } /** * Set the current date @@ -271,7 +251,7 @@ public class DateTimePicker extends FrameLayout { cal.setTimeInMillis(date); setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); - }//实现函数功能——设置当前的时间,参数是date + } /** * Set the current date @@ -283,20 +263,19 @@ public class DateTimePicker extends FrameLayout { * @param minute The current minute */ public void setCurrentDate(int year, int month, - int dayOfMonth, int hourOfDay, int minute) { + int dayOfMonth, int hourOfDay, int minute) { setCurrentYear(year); setCurrentMonth(month); setCurrentDay(dayOfMonth); setCurrentHour(hourOfDay); setCurrentMinute(minute); - }//实现函数功能——设置当前的时间,参数是各详细的变量 + } /** * Get current year * * @return The current year */ - //下面是得到year、month、day等值 public int getCurrentYear() { return mDate.get(Calendar.YEAR); } @@ -467,7 +446,7 @@ public class DateTimePicker extends FrameLayout { mDateSpinner.setDisplayedValues(mDateDisplayValues); mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); mDateSpinner.invalidate(); - }// 对于星期几的算法 + } private void updateAmPmControl() { if (mIs24HourView) { @@ -476,7 +455,7 @@ public class DateTimePicker extends FrameLayout { int index = mIsAm ? Calendar.AM : Calendar.PM; mAmPmSpinner.setValue(index); mAmPmSpinner.setVisibility(View.VISIBLE); - }// 对于上下午操作的算法 + } } private void updateHourControl() { @@ -486,7 +465,7 @@ public class DateTimePicker extends FrameLayout { } else { mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); - }// 对与小时的算法 + } } /** @@ -503,4 +482,4 @@ public class DateTimePicker extends FrameLayout { getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); } } -} \ No newline at end of file +} diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DropdownMenu.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DropdownMenu.java index 965302a..613dc74 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DropdownMenu.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/DropdownMenu.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.micode.notes.ui; import android.content.Context; @@ -29,18 +30,14 @@ import net.micode.notes.R; public class DropdownMenu { private Button mButton; private PopupMenu mPopupMenu; - //声明一个下拉菜单 private Menu mMenu; public DropdownMenu(Context context, Button button, int menuId) { mButton = button; mButton.setBackgroundResource(R.drawable.dropdown_icon); - //设置这个view的背景 mPopupMenu = new PopupMenu(context, mButton); mMenu = mPopupMenu.getMenu(); mPopupMenu.getMenuInflater().inflate(menuId, mMenu); - //MenuInflater是用来实例化Menu目录下的Menu布局文件 - //根据ID来确认menu的内容选项 mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPopupMenu.show(); @@ -51,14 +48,14 @@ public class DropdownMenu { public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); - }//设置菜单的监听 + } } public MenuItem findItem(int id) { return mMenu.findItem(id); - }//对于菜单选项的初始化,根据索引搜索菜单需要的选项 + } public void setTitle(CharSequence title) { mButton.setText(title); - }//布局文件,设置标题 -} \ No newline at end of file + } +} diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java index 5e32e6d..96b77da 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java @@ -30,14 +30,10 @@ import net.micode.notes.data.Notes.NoteColumns; public class FoldersListAdapter extends CursorAdapter { - //CursorAdapter是Cursor和ListView的接口 - //FoldersListAdapter继承了CursorAdapter的类 - //主要作用是便签数据库和用户的交互 - //这里就是用folder(文件夹)的形式展现给用户 public static final String [] PROJECTION = { - NoteColumns.ID, - NoteColumns.SNIPPET - };//调用数据库中便签的ID和片段 + NoteColumns.ID, + NoteColumns.SNIPPET + }; public static final int ID_COLUMN = 0; public static final int NAME_COLUMN = 1; @@ -45,13 +41,12 @@ public class FoldersListAdapter extends CursorAdapter { public FoldersListAdapter(Context context, Cursor c) { super(context, c); // TODO Auto-generated constructor stub - }//数据库操作 + } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { - //ViewGroup是容器 return new FolderListItem(context); - }//创建一个文件夹,对于各文件夹中子标签的初始化 + } @Override public void bindView(View view, Context context, Cursor cursor) { @@ -60,22 +55,20 @@ public class FoldersListAdapter extends CursorAdapter { .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); - }//根据数据库中标签的ID得到标签的各项内容 + } private class FolderListItem extends 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); } @@ -84,4 +77,4 @@ public class FoldersListAdapter extends CursorAdapter { } } -} \ No newline at end of file +} diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 5c44de6..96a9ff8 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package net.micode.notes.ui; import android.app.Activity; @@ -73,8 +74,6 @@ import java.util.regex.Pattern; public class NoteEditActivity extends Activity implements OnClickListener, NoteSettingChangedListener, OnTextViewChangeListener { - //该类主要是针对标签的编辑 - //继承了系统内部许多和监听有关的类 private class HeadViewHolder { public TextView tvModified; @@ -84,7 +83,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, public ImageView ibSetBgColor; } - //使用Map实现数据存储 + private static final Map sBgSelectorBtnsMap = new HashMap(); static { sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); @@ -92,7 +91,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE); sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN); sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE); - //put函数是将指定值和指定键相连 } private static final Map sBgSelectorSelectionMap = new HashMap(); @@ -102,7 +100,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select); sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select); sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); - //put函数是将指定值和指定键相连 } private static final Map sFontSizeBtnsMap = new HashMap(); @@ -111,7 +108,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL); sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM); sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); - //put函数是将指定值和指定键相连 } private static final Map sFontSelectorSelectionMap = new HashMap(); @@ -120,7 +116,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select); sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select); sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); - //put函数是将指定值和指定键相连 } private static final String TAG = "NoteEditActivity"; @@ -128,23 +123,20 @@ public class NoteEditActivity extends Activity implements OnClickListener, private HeadViewHolder mNoteHeaderHolder; private View mHeadViewPanel; - //私有化一个界面操作mHeadViewPanel,对表头的操作 + private View mNoteBgColorSelector; - //私有化一个界面操作mNoteBgColorSelector,对背景颜色的操作 + private View mFontSizeSelector; - //私有化一个界面操作mFontSizeSelector,对标签字体的操作 + private EditText mNoteEditor; - //声明编辑控件,对文本操作 + private View mNoteEditorPanel; - //私有化一个界面操作mNoteEditorPanel,文本编辑的控制板 - //private WorkingNote mWorkingNote; - public WorkingNote mWorkingNote; - //对模板WorkingNote的初始化 + + private WorkingNote mWorkingNote; + private SharedPreferences mSharedPrefs; - //私有化SharedPreferences的数据存储方式 - //它的本质是基于XML文件存储key-value键值对数据 private int mFontSizeId; - //用于操作字体的大小 + private static final String PREFERENCE_FONT_SIZE = "pref_font_size"; private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10; @@ -153,7 +145,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, public static final String TAG_UNCHECKED = String.valueOf('\u25A1'); private LinearLayout mEditTextList; - //线性布局 + private String mUserQuery; private Pattern mPattern; @@ -161,7 +153,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.note_edit); - //对数据库的访问操作 + if (savedInstanceState == null && !initActivityState(getIntent())) { finish(); return; @@ -184,7 +176,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, return; } Log.d(TAG, "Restoring from killed activity"); - }//为防止内存不足时程序的终止,在这里有一个保存现场的函数 + } } private boolean initActivityState(Intent intent) { @@ -196,42 +188,34 @@ public class NoteEditActivity extends Activity implements OnClickListener, if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) { long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); mUserQuery = ""; - //如果用户实例化标签时,系统并未给出标签ID + /** * Starting from the searched result */ - //根据键值查找ID if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) { noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); } - //如果ID在数据库中未找到 + if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) { Intent jump = new Intent(this, NotesListActivity.class); startActivity(jump); - //程序将跳转到上面声明的intent——jump showToast(R.string.error_note_not_exist); finish(); return false; - } - //ID在数据库中找到 - else { + } else { mWorkingNote = WorkingNote.load(this, noteId); if (mWorkingNote == null) { Log.e(TAG, "load note failed with note id" + noteId); - //打印出红色的错误信息 finish(); return false; } } - //setSoftInputMode——软键盘输入模式 getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { - // intent.getAction() - // 大多用于broadcast发送广播时给机制(intent)设置一个action,就是一个字符串 - // 用户可以通过receive(接受)intent,通过 getAction得到的字符串,来决定做什么 + // New note long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); @@ -239,7 +223,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, Notes.TYPE_WIDGET_INVALIDE); int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, ResourceParser.getDefaultBgId(this)); - // intent.getInt(Long、String)Extra是对各变量的语法分析 + // Parse call-record note String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0); @@ -256,17 +240,15 @@ public class NoteEditActivity extends Activity implements OnClickListener, finish(); return false; } - //将电话号码与手机的号码簿相关 } else { mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); mWorkingNote.convertToCallNote(phoneNumber, callDate); - // } } else { mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); - }//创建一个新的WorkingNote + } getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE @@ -287,10 +269,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } private void initNoteScreen() { - //对界面的初始化操作 mNoteEditor.setTextAppearance(this, TextAppearanceResources .getTexAppearanceResource(mFontSizeId)); - //设置外观 if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { switchToListMode(mWorkingNote.getContent()); } else { @@ -314,21 +294,18 @@ public class NoteEditActivity extends Activity implements OnClickListener, */ showAlertHeader(); } - //设置闹钟的显示 + private void showAlertHeader() { if (mWorkingNote.hasClockAlert()) { long time = System.currentTimeMillis(); if (time > mWorkingNote.getAlertDate()) { mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); - } - //如果系统时间大于了闹钟设置的时间,那么闹钟失效 - else { + } else { mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString( mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS)); } mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE); - //显示闹钟开启的图标 } else { mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); @@ -352,29 +329,26 @@ public class NoteEditActivity extends Activity implements OnClickListener, if (!mWorkingNote.existInDatabase()) { saveNote(); } - //在创建一个新的标签时,先在数据库中匹配 - //如果不存在,那么先在数据库中存储 outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState"); } @Override - //MotionEvent是对屏幕触控的传递机制 public boolean dispatchTouchEvent(MotionEvent ev) { if (mNoteBgColorSelector.getVisibility() == View.VISIBLE && !inRangeOfView(mNoteBgColorSelector, ev)) { mNoteBgColorSelector.setVisibility(View.GONE); return true; - }//颜色选择器在屏幕上可见 + } if (mFontSizeSelector.getVisibility() == View.VISIBLE && !inRangeOfView(mFontSizeSelector, ev)) { mFontSizeSelector.setVisibility(View.GONE); return true; - }//字体大小选择器在屏幕上可见 + } return super.dispatchTouchEvent(ev); } - //对屏幕触控的坐标进行操作 + private boolean inRangeOfView(View view, MotionEvent ev) { int []location = new int[2]; view.getLocationOnScreen(location); @@ -383,11 +357,9 @@ public class NoteEditActivity extends Activity implements OnClickListener, if (ev.getX() < x || ev.getX() > (x + view.getWidth()) || ev.getY() < y - || ev.getY() > (y + view.getHeight())) - //如果触控的位置超出了给定的范围,返回false - { - return false; - } + || ev.getY() > (y + view.getHeight())) { + return false; + } return true; } @@ -405,13 +377,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, for (int id : sBgSelectorBtnsMap.keySet()) { ImageView iv = (ImageView) findViewById(id); iv.setOnClickListener(this); - }//对标签各项属性内容的初始化 + } mFontSizeSelector = findViewById(R.id.font_size_selector); for (int id : sFontSizeBtnsMap.keySet()) { View view = findViewById(id); view.setOnClickListener(this); - };//对字体大小的选择 + }; mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); /** @@ -433,7 +405,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } clearSettingState(); } - //和桌面小工具的同步 + private void updateWidget() { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) { @@ -446,7 +418,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { - mWorkingNote.getWidgetId() + mWorkingNote.getWidgetId() }); sendBroadcast(intent); @@ -478,7 +450,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } mFontSizeSelector.setVisibility(View.GONE); } - }//************************存在问题 + } @Override public void onBackPressed() { @@ -509,7 +481,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, } @Override - //对选择菜单的准备 public boolean onPrepareOptionsMenu(Menu menu) { if (isFinishing()) { return true; @@ -518,7 +489,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, menu.clear(); if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) { getMenuInflater().inflate(R.menu.call_note_edit, menu); - // MenuInflater是用来实例化Menu目录下的Menu布局文件的 } else { getMenuInflater().inflate(R.menu.note_edit, menu); } @@ -536,71 +506,45 @@ public class NoteEditActivity extends Activity implements OnClickListener, } @Override - /* - * 函数功能:动态改变菜单选项内容 - * 函数实现:如下注释 - */ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - //根据菜单的id来编剧相关项目 case R.id.menu_new_note: - //创建一个新的便签 createNewNote(); break; case R.id.menu_delete: - //删除便签 AlertDialog.Builder builder = new AlertDialog.Builder(this); - //创建关于删除操作的对话框 builder.setTitle(getString(R.string.alert_title_delete)); - // 设置标签的标题为alert_title_delete builder.setIcon(android.R.drawable.ic_dialog_alert); - //设置对话框图标 builder.setMessage(getString(R.string.alert_message_delete_note)); - //设置对话框内容 builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - //建立按键监听器 public void onClick(DialogInterface dialog, int which) { - //点击所触发事件 deleteCurrentNote(); - // 删除单签便签 finish(); } }); - //添加“YES”按钮 builder.setNegativeButton(android.R.string.cancel, null); - //添加“NO”的按钮 builder.show(); - //显示对话框 break; case R.id.menu_font_size: - //字体大小的编辑 mFontSizeSelector.setVisibility(View.VISIBLE); - // 将字体选择器置为可见 findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); - // 通过id找到相应的大小 break; case R.id.menu_list_mode: - //选择列表模式 mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ? TextNote.MODE_CHECK_LIST : 0); break; case R.id.menu_share: - //菜单共享 getWorkingText(); sendTo(this, mWorkingNote.getContent()); - // 用sendto函数将运行文本发送到遍历的本文内 break; case R.id.menu_send_to_desktop: - //发送到桌面 sendToDesktop(); break; case R.id.menu_alert: - //创建提醒器 setReminder(); break; case R.id.menu_delete_remind: - //删除日期提醒 mWorkingNote.setAlertDate(0, false); break; default: @@ -609,170 +553,111 @@ public class NoteEditActivity extends Activity implements OnClickListener, return true; } - /* - * 函数功能:建立事件提醒器 - * 函数实现:如下注释 - */ private void setReminder() { DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis()); - // 建立修改时间日期的对话框 d.setOnDateTimeSetListener(new OnDateTimeSetListener() { public void OnDateTimeSet(AlertDialog dialog, long date) { mWorkingNote.setAlertDate(date , true); - //选择提醒的日期 } }); - //建立时间日期的监听器 d.show(); - //显示对话框 } /** * Share note to apps that support {@link Intent#ACTION_SEND} action * and {@text/plain} type */ - /* - * 函数功能:共享便签 - * 函数实现:如下注释 - */ private void sendTo(Context context, String info) { Intent intent = new Intent(Intent.ACTION_SEND); - //建立intent链接选项 intent.putExtra(Intent.EXTRA_TEXT, info); - //将需要传递的便签信息放入text文件中 intent.setType("text/plain"); - //编辑连接器的类型 context.startActivity(intent); - //在acti中进行链接 } - /* - * 函数功能:创建一个新的便签 - * 函数实现:如下注释 - */ private void createNewNote() { // Firstly, save current editing notes - //保存当前便签 saveNote(); // For safety, start a new NoteEditActivity finish(); Intent intent = new Intent(this, NoteEditActivity.class); - //设置链接器 intent.setAction(Intent.ACTION_INSERT_OR_EDIT); - //该活动定义为创建或编辑 intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId()); - //将运行便签的id添加到INTENT_EXTRA_FOLDER_ID标记中 startActivity(intent); - //开始activity并链接 } - /* - * 函数功能:删除当前便签 - * 函数实现:如下注释 - */ private void deleteCurrentNote() { if (mWorkingNote.existInDatabase()) { - //假如当前运行的便签内存有数据 HashSet ids = new HashSet(); long id = mWorkingNote.getNoteId(); if (id != Notes.ID_ROOT_FOLDER) { ids.add(id); - //如果不是头文件夹建立一个hash表把便签id存起来 } else { Log.d(TAG, "Wrong note id, should not happen"); - //否则报错 } if (!isSyncMode()) { - //在非同步模式情况下 - //删除操作 if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) { Log.e(TAG, "Delete Note error"); } } else { - //同步模式 - //移动至垃圾文件夹的操作 if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) { Log.e(TAG, "Move notes to trash folder error, should not happens"); } } } mWorkingNote.markDeleted(true); - //将这些标签的删除标记置为true } - /* - * 函数功能:判断是否为同步模式 - * 函数实现:直接看NotesPreferenceActivity中同步名称是否为空 - */ private boolean isSyncMode() { return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } - /* - * 函数功能:设置提醒时间 - * 函数实现:如下注释 - */ public void onClockAlertChanged(long date, boolean set) { /** * User could set clock to an unsaved note, so before setting the * alert clock, we should save the note first */ if (!mWorkingNote.existInDatabase()) { - //首先保存已有的便签 saveNote(); } if (mWorkingNote.getNoteId() > 0) { Intent intent = new Intent(this, AlarmReceiver.class); intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId())); - //若有有运行的便签就是建立一个链接器将标签id都存在uri中 PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); - //设置提醒管理器 showAlertHeader(); if(!set) { alarmManager.cancel(pendingIntent); } else { alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); } - //如果用户设置了时间,就通过提醒管理器设置一个监听事项 } else { /** * There is the condition that user has input nothing (the note is * not worthy saving), we have no note id, remind the user that he * should input something */ - //没有运行的便签就报错 Log.e(TAG, "Clock alert setting error"); showToast(R.string.error_note_empty_for_clock); } } - /* - * 函数功能:Widget发生改变的所触发的事件 - */ public void onWidgetChanged() { - updateWidget();//更新Widget + updateWidget(); } - /* - * 函数功能: 删除编辑文本框所触发的事件 - * 函数实现:如下注释 - */ public void onEditTextDelete(int index, String text) { int childCount = mEditTextList.getChildCount(); if (childCount == 1) { return; } - //没有编辑框的话直接返回 + for (int i = index + 1; i < childCount; i++) { ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) .setIndex(i - 1); - //通过id把编辑框存在便签编辑框中 } mEditTextList.removeViewAt(index); - //删除特定位置的视图 NoteEditText edit = null; if(index == 0) { edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById( @@ -781,101 +666,69 @@ public class NoteEditActivity extends Activity implements OnClickListener, edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById( R.id.et_edit_text); } - //通过id把编辑框存在空的NoteEditText中 int length = edit.length(); edit.append(text); - edit.requestFocus();//请求优先完成该此 编辑 - edit.setSelection(length);//定位到length位置处的条目 + edit.requestFocus(); + edit.setSelection(length); } - /* - * 函数功能:进入编辑文本框所触发的事件 - * 函数实现:如下注释 - */ public void onEditTextEnter(int index, String text) { /** * Should not happen, check for debug */ if(index > mEditTextList.getChildCount()) { Log.e(TAG, "Index out of mEditTextList boundrary, should not happen"); - //越界把偶偶 } View view = getListItem(text, index); mEditTextList.addView(view, index); - //建立一个新的视图并添加到编辑文本框内 NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); - edit.requestFocus();//请求优先操作 - edit.setSelection(0);//定位到起始位置 + edit.requestFocus(); + edit.setSelection(0); for (int i = index + 1; i < mEditTextList.getChildCount(); i++) { ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) .setIndex(i); - //遍历子文本框并设置对应对下标 } } - /* - * 函数功能:切换至列表模式 - * 函数实现:如下注释 - */ private void switchToListMode(String text) { mEditTextList.removeAllViews(); String[] items = text.split("\n"); int index = 0; - //清空所有视图,初始化下标 for (String item : items) { if(!TextUtils.isEmpty(item)) { mEditTextList.addView(getListItem(item, index)); index++; - //遍历所有文本单元并添加到文本框中 } } mEditTextList.addView(getListItem("", index)); mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); - //优先请求此操作 mNoteEditor.setVisibility(View.GONE); - //便签编辑器不可见 mEditTextList.setVisibility(View.VISIBLE); - //将文本编辑框置为可见 } - /* - * 函数功能:获取高亮效果的反馈情况 - * 函数实现:如下注释 - */ private Spannable getHighlightQueryResult(String fullText, String userQuery) { SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); - //新建一个效果选项 if (!TextUtils.isEmpty(userQuery)) { mPattern = Pattern.compile(userQuery); - //将用户的询问进行解析 Matcher m = mPattern.matcher(fullText); - //建立一个状态机检查Pattern并进行匹配 int start = 0; while (m.find(start)) { spannable.setSpan( new BackgroundColorSpan(this.getResources().getColor( R.color.user_query_highlight)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); - //设置背景颜色 start = m.end(); - //跟新起始位置 } } return spannable; } - /* - * 函数功能:获取列表项 - * 函数实现:如下注释 - */ private View getListItem(String item, int index) { View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null); - //创建一个视图 final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); - //创建一个文本编辑框并设置可见性 CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item)); cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -886,15 +739,12 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } }); - //建立一个打钩框并设置监听器 if (item.startsWith(TAG_CHECKED)) { - //选择勾选 cb.setChecked(true); edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); item = item.substring(TAG_CHECKED.length(), item.length()).trim(); } else if (item.startsWith(TAG_UNCHECKED)) { - //选择不勾选 cb.setChecked(false); edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); @@ -903,94 +753,61 @@ public class NoteEditActivity extends Activity implements OnClickListener, edit.setOnTextViewChangeListener(this); edit.setIndex(index); edit.setText(getHighlightQueryResult(item, mUserQuery)); - //运行编辑框的监听器对该行为作出反应,并设置下标及文本内容 return view; } - /* - * 函数功能:便签内容发生改变所 触发的事件 - * 函数实现:如下注释 - */ public void onTextChange(int index, boolean hasText) { if (index >= mEditTextList.getChildCount()) { Log.e(TAG, "Wrong index, should not happen"); return; - //越界报错 } if(hasText) { mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE); } else { mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE); } - //如果内容不为空则将其子编辑框可见性置为可见,否则不可见 } - /* - * 函数功能:检查模式和列表模式的切换 - * 函数实现:如下注释 - */ public void onCheckListModeChanged(int oldMode, int newMode) { if (newMode == TextNote.MODE_CHECK_LIST) { switchToListMode(mNoteEditor.getText().toString()); - //检查模式切换到列表模式 } else { if (!getWorkingText()) { mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", "")); } - //若是获取到文本就改变其检查标记 mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); mEditTextList.setVisibility(View.GONE); mNoteEditor.setVisibility(View.VISIBLE); - //修改文本编辑器的内容和可见性 } } - /* - * 函数功能:设置勾选选项表并返回是否勾选的标记 - * 函数实现:如下注释 - */ private boolean getWorkingText() { boolean hasChecked = false; - //初始化check标记 if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { - // 若模式为CHECK_LIST StringBuilder sb = new StringBuilder(); - //创建可变字符串 for (int i = 0; i < mEditTextList.getChildCount(); i++) { View view = mEditTextList.getChildAt(i); - //遍历所有子编辑框的视图 NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); if (!TextUtils.isEmpty(edit.getText())) { - //若文本不为空 if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) { - //该选项框已打钩 sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n"); hasChecked = true; - //扩展字符串为已打钩并把标记置true } else { sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n"); - //扩展字符串添加未打钩 } } } mWorkingNote.setWorkingText(sb.toString()); - //利用编辑好的字符串设置运行便签的内容 } else { mWorkingNote.setWorkingText(mNoteEditor.getText().toString()); - // 若不是该模式直接用编辑器中的内容设置运行中标签的内容 } return hasChecked; } - /* - * 函数功能:保存便签 - * 函数实现:如下注释 - */ private boolean saveNote() { getWorkingText(); boolean saved = mWorkingNote.saveNote(); - //运行 getWorkingText()之后保存 if (saved) { /** * There are two modes from List view to edit view, open one note, @@ -999,16 +816,11 @@ public class NoteEditActivity extends Activity implements OnClickListener, * new node requires to the top of the list. This code * {@link #RESULT_OK} is used to identify the create/edit state */ - //如英文注释所说链接RESULT_OK是为了识别保存的2种情况,一是创建后保存,二是修改后保存 setResult(RESULT_OK); } return saved; } - /* - * 函数功能:将便签发送至桌面 - * 函数实现:如下注释 - */ private void sendToDesktop() { /** * Before send message to home, we should make sure that current @@ -1017,16 +829,12 @@ public class NoteEditActivity extends Activity implements OnClickListener, */ if (!mWorkingNote.existInDatabase()) { saveNote(); - //若不存在数据也就是新的标签就保存起来先 } if (mWorkingNote.getNoteId() > 0) { - //若是有内容 Intent sender = new Intent(); Intent shortcutIntent = new Intent(this, NoteEditActivity.class); - //建立发送到桌面的连接器 shortcutIntent.setAction(Intent.ACTION_VIEW); - //链接为一个视图 shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId()); sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); sender.putExtra(Intent.EXTRA_SHORTCUT_NAME, @@ -1034,12 +842,9 @@ public class NoteEditActivity extends Activity implements OnClickListener, sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(this, R.drawable.icon_app)); sender.putExtra("duplicate", true); - //将便签的相关信息都添加到要发送的文件里 sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); - //设置sneder的行为是发送 showToast(R.string.info_note_enter_desktop); sendBroadcast(sender); - //显示到桌面 } else { /** * There is the condition that user has input nothing (the note is @@ -1048,35 +853,21 @@ public class NoteEditActivity extends Activity implements OnClickListener, */ Log.e(TAG, "Send to desktop error"); showToast(R.string.error_note_empty_for_send_to_desktop); - //空便签直接报错 } } - /* - * 函数功能:编辑小图标的标题 - * 函数实现:如下注释 - */ private String makeShortcutIconTitle(String content) { content = content.replace(TAG_CHECKED, ""); content = content.replace(TAG_UNCHECKED, ""); return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0, SHORTCUT_ICON_TITLE_MAX_LEN) : content; - //直接设置为content中的内容并返回,有勾选和未勾选2种 } - /* - * 函数功能:显示提示的视图 - * 函数实现:根据下标显示对应的提示 - */ private void showToast(int resId) { showToast(resId, Toast.LENGTH_SHORT); } - /* - * 函数功能:持续显示提示的视图 - * 函数实现:根据下标和持续的时间(duration)编辑提示视图并显示 - */ private void showToast(int resId, int duration) { Toast.makeText(this, resId, duration).show(); } -} \ No newline at end of file +} diff --git a/src/Notesmaster/app/src/main/res/layout/activity_main.xml b/src/Notesmaster/app/src/main/res/layout/activity_main.xml index 86a5d97..e061ed5 100644 --- a/src/Notesmaster/app/src/main/res/layout/activity_main.xml +++ b/src/Notesmaster/app/src/main/res/layout/activity_main.xml @@ -1,19 +1,156 @@ - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/data/Contact.java b/src/Notesmaster/app/src/test/java/net/micode/notes/data/Contact.java new file mode 100644 index 0000000..d97ac5d --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/data/Contact.java @@ -0,0 +1,73 @@ +/* + * 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.data; + +import android.content.Context; +import android.database.Cursor; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.Data; +import android.telephony.PhoneNumberUtils; +import android.util.Log; + +import java.util.HashMap; + +public class Contact { + private static HashMap sContactCache; + private static final String TAG = "Contact"; + + private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER + + ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'" + + " AND " + Data.RAW_CONTACT_ID + " IN " + + "(SELECT raw_contact_id " + + " FROM phone_lookup" + + " WHERE min_match = '+')"; + + public static String getContact(Context context, String phoneNumber) { + if(sContactCache == null) { + sContactCache = new HashMap(); + } + + if(sContactCache.containsKey(phoneNumber)) { + return sContactCache.get(phoneNumber); + } + + String selection = CALLER_ID_SELECTION.replace("+", + PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)); + Cursor cursor = context.getContentResolver().query( + Data.CONTENT_URI, + new String [] { Phone.DISPLAY_NAME }, + selection, + new String[] { phoneNumber }, + null); + + if (cursor != null && cursor.moveToFirst()) { + try { + String name = cursor.getString(0); + sContactCache.put(phoneNumber, name); + return name; + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, " Cursor get string error " + e.toString()); + return null; + } finally { + cursor.close(); + } + } else { + Log.d(TAG, "No contact matched with number:" + phoneNumber); + return null; + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/data/Notes.java b/src/Notesmaster/app/src/test/java/net/micode/notes/data/Notes.java new file mode 100644 index 0000000..f240604 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/data/Notes.java @@ -0,0 +1,279 @@ +/* + * 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.data; + +import android.net.Uri; +public class Notes { + public static final String AUTHORITY = "micode_notes"; + public static final String TAG = "Notes"; + public static final int TYPE_NOTE = 0; + public static final int TYPE_FOLDER = 1; + public static final int TYPE_SYSTEM = 2; + + /** + * Following IDs are system folders' identifiers + * {@link Notes#ID_ROOT_FOLDER } is default folder + * {@link Notes#ID_TEMPARAY_FOLDER } is for notes belonging no folder + * {@link Notes#ID_CALL_RECORD_FOLDER} is to store call records + */ + public static final int ID_ROOT_FOLDER = 0; + public static final int ID_TEMPARAY_FOLDER = -1; + public static final int ID_CALL_RECORD_FOLDER = -2; + public static final int ID_TRASH_FOLER = -3; + + public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date"; + public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id"; + public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id"; + public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type"; + public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id"; + public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date"; + + public static final int TYPE_WIDGET_INVALIDE = -1; + public static final int TYPE_WIDGET_2X = 0; + public static final int TYPE_WIDGET_4X = 1; + + public static class DataConstants { + public static final String NOTE = TextNote.CONTENT_ITEM_TYPE; + public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE; + } + + /** + * Uri to query all notes and folders + */ + public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note"); + + /** + * Uri to query data + */ + public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data"); + + public interface NoteColumns { + /** + * The unique ID for a row + *

    Type: INTEGER (long)

    + */ + public static final String ID = "_id"; + + /** + * The parent's id for note or folder + *

    Type: INTEGER (long)

    + */ + public static final String PARENT_ID = "parent_id"; + + /** + * Created data for note or folder + *

    Type: INTEGER (long)

    + */ + public static final String CREATED_DATE = "created_date"; + + /** + * Latest modified date + *

    Type: INTEGER (long)

    + */ + public static final String MODIFIED_DATE = "modified_date"; + + + /** + * Alert date + *

    Type: INTEGER (long)

    + */ + public static final String ALERTED_DATE = "alert_date"; + + /** + * Folder's name or text content of note + *

    Type: TEXT

    + */ + public static final String SNIPPET = "snippet"; + + /** + * Note's widget id + *

    Type: INTEGER (long)

    + */ + public static final String WIDGET_ID = "widget_id"; + + /** + * Note's widget type + *

    Type: INTEGER (long)

    + */ + public static final String WIDGET_TYPE = "widget_type"; + + /** + * Note's background color's id + *

    Type: INTEGER (long)

    + */ + public static final String BG_COLOR_ID = "bg_color_id"; + + /** + * For text note, it doesn't has attachment, for multi-media + * note, it has at least one attachment + *

    Type: INTEGER

    + */ + public static final String HAS_ATTACHMENT = "has_attachment"; + + /** + * Folder's count of notes + *

    Type: INTEGER (long)

    + */ + public static final String NOTES_COUNT = "notes_count"; + + /** + * The file type: folder or note + *

    Type: INTEGER

    + */ + public static final String TYPE = "type"; + + /** + * The last sync id + *

    Type: INTEGER (long)

    + */ + public static final String SYNC_ID = "sync_id"; + + /** + * Sign to indicate local modified or not + *

    Type: INTEGER

    + */ + public static final String LOCAL_MODIFIED = "local_modified"; + + /** + * Original parent id before moving into temporary folder + *

    Type : INTEGER

    + */ + public static final String ORIGIN_PARENT_ID = "origin_parent_id"; + + /** + * The gtask id + *

    Type : TEXT

    + */ + public static final String GTASK_ID = "gtask_id"; + + /** + * The version code + *

    Type : INTEGER (long)

    + */ + public static final String VERSION = "version"; + } + + public interface DataColumns { + /** + * The unique ID for a row + *

    Type: INTEGER (long)

    + */ + public static final String ID = "_id"; + + /** + * The MIME type of the item represented by this row. + *

    Type: Text

    + */ + public static final String MIME_TYPE = "mime_type"; + + /** + * The reference id to note that this data belongs to + *

    Type: INTEGER (long)

    + */ + public static final String NOTE_ID = "note_id"; + + /** + * Created data for note or folder + *

    Type: INTEGER (long)

    + */ + public static final String CREATED_DATE = "created_date"; + + /** + * Latest modified date + *

    Type: INTEGER (long)

    + */ + public static final String MODIFIED_DATE = "modified_date"; + + /** + * Data's content + *

    Type: TEXT

    + */ + public static final String CONTENT = "content"; + + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * integer data type + *

    Type: INTEGER

    + */ + public static final String DATA1 = "data1"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * integer data type + *

    Type: INTEGER

    + */ + public static final String DATA2 = "data2"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *

    Type: TEXT

    + */ + public static final String DATA3 = "data3"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *

    Type: TEXT

    + */ + public static final String DATA4 = "data4"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *

    Type: TEXT

    + */ + public static final String DATA5 = "data5"; + } + + public static final class TextNote implements DataColumns { + /** + * Mode to indicate the text in check list mode or not + *

    Type: Integer 1:check list mode 0: normal mode

    + */ + public static final String MODE = DATA1; + + public static final int MODE_CHECK_LIST = 1; + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note"; + + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note"; + + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note"); + } + + public static final class CallNote implements DataColumns { + /** + * Call date for this record + *

    Type: INTEGER (long)

    + */ + public static final String CALL_DATE = DATA1; + + /** + * Phone number for this record + *

    Type: TEXT

    + */ + public static final String PHONE_NUMBER = DATA3; + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note"; + + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note"; + + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note"); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesDatabaseHelper.java b/src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesDatabaseHelper.java new file mode 100644 index 0000000..ffe5d57 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesDatabaseHelper.java @@ -0,0 +1,362 @@ +/* + * 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.data; + +import android.content.ContentValues; +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.DataConstants; +import net.micode.notes.data.Notes.NoteColumns; + + +public class NotesDatabaseHelper extends SQLiteOpenHelper { + private static final String DB_NAME = "note.db"; + + private static final int DB_VERSION = 4; + + public interface TABLE { + public static final String NOTE = "note"; + + public static final String DATA = "data"; + } + + private static final String TAG = "NotesDatabaseHelper"; + + private static NotesDatabaseHelper mInstance; + + private static final String CREATE_NOTE_TABLE_SQL = + "CREATE TABLE " + TABLE.NOTE + "(" + + NoteColumns.ID + " INTEGER PRIMARY KEY," + + NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," + + NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," + + NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," + + NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" + + ")"; + + private static final String CREATE_DATA_TABLE_SQL = + "CREATE TABLE " + TABLE.DATA + "(" + + DataColumns.ID + " INTEGER PRIMARY KEY," + + DataColumns.MIME_TYPE + " TEXT NOT NULL," + + DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA1 + " INTEGER," + + DataColumns.DATA2 + " INTEGER," + + DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" + + ")"; + + private static final String CREATE_DATA_NOTE_ID_INDEX_SQL = + "CREATE INDEX IF NOT EXISTS note_id_index ON " + + TABLE.DATA + "(" + DataColumns.NOTE_ID + ");"; + + /** + * Increase folder's note count when move note to the folder + */ + private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER increase_folder_count_on_update "+ + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + + " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + + " END"; + + /** + * Decrease folder's note count when move note from folder + */ + private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER decrease_folder_count_on_update " + + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" + + " END"; + + /** + * Increase folder's note count when insert new note to the folder + */ + private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER = + "CREATE TRIGGER increase_folder_count_on_insert " + + " AFTER INSERT ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + + " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + + " END"; + + /** + * Decrease folder's note count when delete note from the folder + */ + private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER = + "CREATE TRIGGER decrease_folder_count_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0;" + + " END"; + + /** + * Update note's content when insert data with type {@link DataConstants#NOTE} + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER = + "CREATE TRIGGER update_note_content_on_insert " + + " AFTER INSERT ON " + TABLE.DATA + + " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Update note's content when data with {@link DataConstants#NOTE} type has changed + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER update_note_content_on_update " + + " AFTER UPDATE ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Update note's content when data with {@link DataConstants#NOTE} type has deleted + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER = + "CREATE TRIGGER update_note_content_on_delete " + + " AFTER delete ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=''" + + " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Delete datas belong to note which has been deleted + */ + private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER = + "CREATE TRIGGER delete_data_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.DATA + + " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + /** + * Delete notes belong to folder which has been deleted + */ + private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER = + "CREATE TRIGGER folder_delete_notes_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + /** + * Move notes belong to folder which has been moved to trash folder + */ + private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER = + "CREATE TRIGGER folder_move_notes_on_trash " + + " AFTER UPDATE ON " + TABLE.NOTE + + " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + public NotesDatabaseHelper(Context context) { + super(context, DB_NAME, null, DB_VERSION); + } + + public void createNoteTable(SQLiteDatabase db) { + db.execSQL(CREATE_NOTE_TABLE_SQL); + reCreateNoteTableTriggers(db); + createSystemFolder(db); + Log.d(TAG, "note table has been created"); + } + + private void reCreateNoteTableTriggers(SQLiteDatabase db) { + db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS delete_data_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS folder_delete_notes_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS folder_move_notes_on_trash"); + + db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); + db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); + db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER); + db.execSQL(NOTE_DELETE_DATA_ON_DELETE_TRIGGER); + db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER); + db.execSQL(FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER); + db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER); + } + + private void createSystemFolder(SQLiteDatabase db) { + ContentValues values = new ContentValues(); + + /** + * call record foler for call notes + */ + values.put(NoteColumns.ID, Notes.ID_CALL_RECORD_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * root folder which is default folder + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * temporary folder which is used for moving note + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * create trash folder + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + } + + public void createDataTable(SQLiteDatabase db) { + db.execSQL(CREATE_DATA_TABLE_SQL); + reCreateDataTableTriggers(db); + db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL); + Log.d(TAG, "data table has been created"); + } + + private void reCreateDataTableTriggers(SQLiteDatabase db) { + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_delete"); + + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER); + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER); + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER); + } + + static synchronized NotesDatabaseHelper getInstance(Context context) { + if (mInstance == null) { + mInstance = new NotesDatabaseHelper(context); + } + return mInstance; + } + + @Override + public void onCreate(SQLiteDatabase db) { + createNoteTable(db); + createDataTable(db); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + boolean reCreateTriggers = false; + boolean skipV2 = false; + + if (oldVersion == 1) { + upgradeToV2(db); + skipV2 = true; // this upgrade including the upgrade from v2 to v3 + oldVersion++; + } + + if (oldVersion == 2 && !skipV2) { + upgradeToV3(db); + reCreateTriggers = true; + oldVersion++; + } + + if (oldVersion == 3) { + upgradeToV4(db); + oldVersion++; + } + + if (reCreateTriggers) { + reCreateNoteTableTriggers(db); + reCreateDataTableTriggers(db); + } + + if (oldVersion != newVersion) { + throw new IllegalStateException("Upgrade notes database to version " + newVersion + + "fails"); + } + } + + private void upgradeToV2(SQLiteDatabase db) { + db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); + db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA); + createNoteTable(db); + createDataTable(db); + } + + private void upgradeToV3(SQLiteDatabase db) { + // drop unused triggers + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_update"); + // add a column for gtask id + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.GTASK_ID + + " TEXT NOT NULL DEFAULT ''"); + // add a trash system folder + ContentValues values = new ContentValues(); + values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + } + + private void upgradeToV4(SQLiteDatabase db) { + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION + + " INTEGER NOT NULL DEFAULT 0"); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesProvider.java b/src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesProvider.java new file mode 100644 index 0000000..edb0a60 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/data/NotesProvider.java @@ -0,0 +1,305 @@ +/* + * 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.data; + + +import android.app.SearchManager; +import android.content.ContentProvider; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Intent; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Log; + +import net.micode.notes.R; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.data.NotesDatabaseHelper.TABLE; + + +public class NotesProvider extends ContentProvider { + private static final UriMatcher mMatcher; + + private NotesDatabaseHelper mHelper; + + private static final String TAG = "NotesProvider"; + + private static final int URI_NOTE = 1; + private static final int URI_NOTE_ITEM = 2; + private static final int URI_DATA = 3; + private static final int URI_DATA_ITEM = 4; + + private static final int URI_SEARCH = 5; + private static final int URI_SEARCH_SUGGEST = 6; + + static { + mMatcher = new UriMatcher(UriMatcher.NO_MATCH); + mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); + mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); + mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); + mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); + mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST); + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST); + } + + /** + * x'0A' represents the '\n' character in sqlite. For title and content in the search result, + * we will trim '\n' and white space in order to show more information. + */ + private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," + + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + "," + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + "," + + R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + "," + + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," + + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; + + private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION + + " FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.SNIPPET + " LIKE ?" + + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE; + + @Override + public boolean onCreate() { + mHelper = NotesDatabaseHelper.getInstance(getContext()); + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + Cursor c = null; + SQLiteDatabase db = mHelper.getReadableDatabase(); + String id = null; + switch (mMatcher.match(uri)) { + case URI_NOTE: + c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, + sortOrder); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id + + parseSelection(selection), selectionArgs, null, null, sortOrder); + break; + case URI_DATA: + c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null, + sortOrder); + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs, null, null, sortOrder); + break; + case URI_SEARCH: + case URI_SEARCH_SUGGEST: + if (sortOrder != null || projection != null) { + throw new IllegalArgumentException( + "do not specify sortOrder, selection, selectionArgs, or projection" + "with this query"); + } + + String searchString = null; + if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) { + if (uri.getPathSegments().size() > 1) { + searchString = uri.getPathSegments().get(1); + } + } else { + searchString = uri.getQueryParameter("pattern"); + } + + if (TextUtils.isEmpty(searchString)) { + return null; + } + + try { + searchString = String.format("%%%s%%", searchString); + c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, + new String[] { searchString }); + } catch (IllegalStateException ex) { + Log.e(TAG, "got exception: " + ex.toString()); + } + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + if (c != null) { + c.setNotificationUri(getContext().getContentResolver(), uri); + } + return c; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + SQLiteDatabase db = mHelper.getWritableDatabase(); + long dataId = 0, noteId = 0, insertedId = 0; + switch (mMatcher.match(uri)) { + case URI_NOTE: + insertedId = noteId = db.insert(TABLE.NOTE, null, values); + break; + case URI_DATA: + if (values.containsKey(DataColumns.NOTE_ID)) { + noteId = values.getAsLong(DataColumns.NOTE_ID); + } else { + Log.d(TAG, "Wrong data format without note id:" + values.toString()); + } + insertedId = dataId = db.insert(TABLE.DATA, null, values); + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + // Notify the note uri + if (noteId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null); + } + + // Notify the data uri + if (dataId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); + } + + return ContentUris.withAppendedId(uri, insertedId); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + int count = 0; + String id = null; + SQLiteDatabase db = mHelper.getWritableDatabase(); + boolean deleteData = false; + switch (mMatcher.match(uri)) { + case URI_NOTE: + selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; + count = db.delete(TABLE.NOTE, selection, selectionArgs); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + /** + * ID that smaller than 0 is system folder which is not allowed to + * trash + */ + long noteId = Long.valueOf(id); + if (noteId <= 0) { + break; + } + count = db.delete(TABLE.NOTE, + NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); + break; + case URI_DATA: + count = db.delete(TABLE.DATA, selection, selectionArgs); + deleteData = true; + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + count = db.delete(TABLE.DATA, + DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); + deleteData = true; + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + if (count > 0) { + if (deleteData) { + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + getContext().getContentResolver().notifyChange(uri, null); + } + return count; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + int count = 0; + String id = null; + SQLiteDatabase db = mHelper.getWritableDatabase(); + boolean updateData = false; + switch (mMatcher.match(uri)) { + case URI_NOTE: + increaseNoteVersion(-1, selection, selectionArgs); + count = db.update(TABLE.NOTE, values, selection, selectionArgs); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); + count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id + + parseSelection(selection), selectionArgs); + break; + case URI_DATA: + count = db.update(TABLE.DATA, values, selection, selectionArgs); + updateData = true; + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs); + updateData = true; + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + + if (count > 0) { + if (updateData) { + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + getContext().getContentResolver().notifyChange(uri, null); + } + return count; + } + + private String parseSelection(String selection) { + return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); + } + + private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { + StringBuilder sql = new StringBuilder(120); + sql.append("UPDATE "); + sql.append(TABLE.NOTE); + sql.append(" SET "); + sql.append(NoteColumns.VERSION); + sql.append("=" + NoteColumns.VERSION + "+1 "); + + if (id > 0 || !TextUtils.isEmpty(selection)) { + sql.append(" WHERE "); + } + if (id > 0) { + sql.append(NoteColumns.ID + "=" + String.valueOf(id)); + } + if (!TextUtils.isEmpty(selection)) { + String selectString = id > 0 ? parseSelection(selection) : selection; + for (String args : selectionArgs) { + selectString = selectString.replaceFirst("\\?", args); + } + sql.append(selectString); + } + + mHelper.getWritableDatabase().execSQL(sql.toString()); + } + + @Override + public String getType(Uri uri) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/MetaData.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/MetaData.java new file mode 100644 index 0000000..3a2050b --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/MetaData.java @@ -0,0 +1,82 @@ +/* + * 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.database.Cursor; +import android.util.Log; + +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class MetaData extends Task { + private final static String TAG = MetaData.class.getSimpleName(); + + private String mRelatedGid = null; + + public void setMeta(String gid, JSONObject metaInfo) { + try { + metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); + } catch (JSONException e) { + Log.e(TAG, "failed to put related gid"); + } + setNotes(metaInfo.toString()); + setName(GTaskStringUtils.META_NOTE_NAME); + } + + public String getRelatedGid() { + return mRelatedGid; + } + + @Override + public boolean isWorthSaving() { + return getNotes() != null; + } + + @Override + public void setContentByRemoteJSON(JSONObject js) { + super.setContentByRemoteJSON(js); + if (getNotes() != null) { + try { + JSONObject metaInfo = new JSONObject(getNotes().trim()); + mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); + } catch (JSONException e) { + Log.w(TAG, "failed to get related gid"); + mRelatedGid = null; + } + } + } + + @Override + public void setContentByLocalJSON(JSONObject js) { + // this function should not be called + throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); + } + + @Override + public JSONObject getLocalJSONFromContent() { + throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); + } + + @Override + public int getSyncAction(Cursor c) { + throw new IllegalAccessError("MetaData:getSyncAction should not be called"); + } + +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Node.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Node.java new file mode 100644 index 0000000..63950e0 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Node.java @@ -0,0 +1,101 @@ +/* + * 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.database.Cursor; + +import org.json.JSONObject; + +public abstract class Node { + public static final int SYNC_ACTION_NONE = 0; + + public static final int SYNC_ACTION_ADD_REMOTE = 1; + + public static final int SYNC_ACTION_ADD_LOCAL = 2; + + public static final int SYNC_ACTION_DEL_REMOTE = 3; + + public static final int SYNC_ACTION_DEL_LOCAL = 4; + + public static final int SYNC_ACTION_UPDATE_REMOTE = 5; + + public static final int SYNC_ACTION_UPDATE_LOCAL = 6; + + public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; + + public static final int SYNC_ACTION_ERROR = 8; + + private String mGid; + + private String mName; + + private long mLastModified; + + private boolean mDeleted; + + public Node() { + mGid = null; + mName = ""; + mLastModified = 0; + mDeleted = false; + } + + public abstract JSONObject getCreateAction(int actionId); + + public abstract JSONObject getUpdateAction(int actionId); + + public abstract void setContentByRemoteJSON(JSONObject js); + + public abstract void setContentByLocalJSON(JSONObject js); + + public abstract JSONObject getLocalJSONFromContent(); + + public abstract int getSyncAction(Cursor c); + + public void setGid(String gid) { + this.mGid = gid; + } + + public void setName(String name) { + this.mName = name; + } + + public void setLastModified(long lastModified) { + this.mLastModified = lastModified; + } + + public void setDeleted(boolean deleted) { + this.mDeleted = deleted; + } + + public String getGid() { + return this.mGid; + } + + public String getName() { + return this.mName; + } + + public long getLastModified() { + return this.mLastModified; + } + + public boolean getDeleted() { + return this.mDeleted; + } + +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlData.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlData.java new file mode 100644 index 0000000..d3ec3be --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlData.java @@ -0,0 +1,189 @@ +/* + * 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.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +import net.micode.notes.data.Notes; +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.NotesDatabaseHelper.TABLE; +import net.micode.notes.gtask.exception.ActionFailureException; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class SqlData { + private static final String TAG = SqlData.class.getSimpleName(); + + private static final int INVALID_ID = -99999; + + public static final String[] PROJECTION_DATA = new String[] { + DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, + DataColumns.DATA3 + }; + + public static final int DATA_ID_COLUMN = 0; + + public static final int DATA_MIME_TYPE_COLUMN = 1; + + public static final int DATA_CONTENT_COLUMN = 2; + + public static final int DATA_CONTENT_DATA_1_COLUMN = 3; + + public static final int DATA_CONTENT_DATA_3_COLUMN = 4; + + private ContentResolver mContentResolver; + + private boolean mIsCreate; + + private long mDataId; + + private String mDataMimeType; + + private String mDataContent; + + private long mDataContentData1; + + private String mDataContentData3; + + private ContentValues mDiffDataValues; + + public SqlData(Context context) { + mContentResolver = context.getContentResolver(); + mIsCreate = true; + mDataId = INVALID_ID; + mDataMimeType = DataConstants.NOTE; + mDataContent = ""; + mDataContentData1 = 0; + mDataContentData3 = ""; + mDiffDataValues = new ContentValues(); + } + + public SqlData(Context context, Cursor c) { + mContentResolver = context.getContentResolver(); + mIsCreate = false; + loadFromCursor(c); + mDiffDataValues = new ContentValues(); + } + + private void loadFromCursor(Cursor c) { + mDataId = c.getLong(DATA_ID_COLUMN); + mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); + mDataContent = c.getString(DATA_CONTENT_COLUMN); + mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); + mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); + } + + public void setContent(JSONObject js) throws JSONException { + long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; + if (mIsCreate || mDataId != dataId) { + mDiffDataValues.put(DataColumns.ID, dataId); + } + mDataId = dataId; + + String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE) + : DataConstants.NOTE; + if (mIsCreate || !mDataMimeType.equals(dataMimeType)) { + mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); + } + mDataMimeType = dataMimeType; + + String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : ""; + if (mIsCreate || !mDataContent.equals(dataContent)) { + mDiffDataValues.put(DataColumns.CONTENT, dataContent); + } + mDataContent = dataContent; + + long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0; + if (mIsCreate || mDataContentData1 != dataContentData1) { + mDiffDataValues.put(DataColumns.DATA1, dataContentData1); + } + mDataContentData1 = dataContentData1; + + String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : ""; + if (mIsCreate || !mDataContentData3.equals(dataContentData3)) { + mDiffDataValues.put(DataColumns.DATA3, dataContentData3); + } + mDataContentData3 = dataContentData3; + } + + public JSONObject getContent() throws JSONException { + if (mIsCreate) { + Log.e(TAG, "it seems that we haven't created this in database yet"); + return null; + } + JSONObject js = new JSONObject(); + js.put(DataColumns.ID, mDataId); + js.put(DataColumns.MIME_TYPE, mDataMimeType); + js.put(DataColumns.CONTENT, mDataContent); + js.put(DataColumns.DATA1, mDataContentData1); + js.put(DataColumns.DATA3, mDataContentData3); + return js; + } + + public void commit(long noteId, boolean validateVersion, long version) { + + if (mIsCreate) { + if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { + mDiffDataValues.remove(DataColumns.ID); + } + + mDiffDataValues.put(DataColumns.NOTE_ID, noteId); + Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); + try { + mDataId = Long.valueOf(uri.getPathSegments().get(1)); + } catch (NumberFormatException e) { + Log.e(TAG, "Get note id error :" + e.toString()); + throw new ActionFailureException("create note failed"); + } + } else { + if (mDiffDataValues.size() > 0) { + int result = 0; + if (!validateVersion) { + result = mContentResolver.update(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); + } else { + result = mContentResolver.update(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, + " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.VERSION + "=?)", new String[] { + String.valueOf(noteId), String.valueOf(version) + }); + } + if (result == 0) { + Log.w(TAG, "there is no update. maybe user updates note when syncing"); + } + } + } + + mDiffDataValues.clear(); + mIsCreate = false; + } + + public long getId() { + return mDataId; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlNote.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlNote.java new file mode 100644 index 0000000..79a4095 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/SqlNote.java @@ -0,0 +1,505 @@ +/* + * 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; +import android.database.Cursor; +import android.net.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; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + + +public class SqlNote { + private static final String TAG = SqlNote.class.getSimpleName(); + + private static final int INVALID_ID = -99999; + + public static final String[] PROJECTION_NOTE = new String[] { + NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, + NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE, + NoteColumns.NOTES_COUNT, NoteColumns.PARENT_ID, NoteColumns.SNIPPET, NoteColumns.TYPE, + NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, NoteColumns.SYNC_ID, + NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID, + NoteColumns.VERSION + }; + + public static final int ID_COLUMN = 0; + + public static final int ALERTED_DATE_COLUMN = 1; + + public static final int BG_COLOR_ID_COLUMN = 2; + + public static final int CREATED_DATE_COLUMN = 3; + + public static final int HAS_ATTACHMENT_COLUMN = 4; + + public static final int MODIFIED_DATE_COLUMN = 5; + + public static final int NOTES_COUNT_COLUMN = 6; + + public static final int PARENT_ID_COLUMN = 7; + + public static final int SNIPPET_COLUMN = 8; + + public static final int TYPE_COLUMN = 9; + + public static final int WIDGET_ID_COLUMN = 10; + + public static final int WIDGET_TYPE_COLUMN = 11; + + public static final int SYNC_ID_COLUMN = 12; + + public static final int LOCAL_MODIFIED_COLUMN = 13; + + public static final int ORIGIN_PARENT_ID_COLUMN = 14; + + public static final int GTASK_ID_COLUMN = 15; + + public static final int VERSION_COLUMN = 16; + + private Context mContext; + + private ContentResolver mContentResolver; + + private boolean mIsCreate; + + private long mId; + + private long mAlertDate; + + private int mBgColorId; + + private long mCreatedDate; + + private int mHasAttachment; + + private long mModifiedDate; + + private long mParentId; + + private String mSnippet; + + private int mType; + + private int mWidgetId; + + private int mWidgetType; + + private long mOriginParent; + + private long mVersion; + + private ContentValues mDiffNoteValues; + + private ArrayList mDataList; + + public SqlNote(Context context) { + mContext = context; + mContentResolver = context.getContentResolver(); + mIsCreate = true; + mId = INVALID_ID; + mAlertDate = 0; + mBgColorId = ResourceParser.getDefaultBgId(context); + mCreatedDate = System.currentTimeMillis(); + mHasAttachment = 0; + mModifiedDate = System.currentTimeMillis(); + mParentId = 0; + mSnippet = ""; + mType = Notes.TYPE_NOTE; + mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; + mWidgetType = Notes.TYPE_WIDGET_INVALIDE; + mOriginParent = 0; + mVersion = 0; + mDiffNoteValues = new ContentValues(); + mDataList = new ArrayList(); + } + + public SqlNote(Context context, Cursor c) { + mContext = context; + mContentResolver = context.getContentResolver(); + mIsCreate = false; + loadFromCursor(c); + mDataList = new ArrayList(); + if (mType == Notes.TYPE_NOTE) + loadDataContent(); + mDiffNoteValues = new ContentValues(); + } + + public SqlNote(Context context, long id) { + mContext = context; + mContentResolver = context.getContentResolver(); + mIsCreate = false; + loadFromCursor(id); + mDataList = new ArrayList(); + if (mType == Notes.TYPE_NOTE) + loadDataContent(); + mDiffNoteValues = new ContentValues(); + + } + + private void loadFromCursor(long id) { + Cursor c = null; + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)", + new String[] { + String.valueOf(id) + }, null); + if (c != null) { + c.moveToNext(); + loadFromCursor(c); + } else { + Log.w(TAG, "loadFromCursor: cursor = null"); + } + } finally { + if (c != null) + c.close(); + } + } + + private void loadFromCursor(Cursor c) { + mId = c.getLong(ID_COLUMN); + mAlertDate = c.getLong(ALERTED_DATE_COLUMN); + mBgColorId = c.getInt(BG_COLOR_ID_COLUMN); + mCreatedDate = c.getLong(CREATED_DATE_COLUMN); + mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN); + mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN); + mParentId = c.getLong(PARENT_ID_COLUMN); + mSnippet = c.getString(SNIPPET_COLUMN); + mType = c.getInt(TYPE_COLUMN); + mWidgetId = c.getInt(WIDGET_ID_COLUMN); + mWidgetType = c.getInt(WIDGET_TYPE_COLUMN); + mVersion = c.getLong(VERSION_COLUMN); + } + + private void loadDataContent() { + Cursor c = null; + mDataList.clear(); + try { + c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA, + "(note_id=?)", new String[] { + String.valueOf(mId) + }, null); + if (c != null) { + if (c.getCount() == 0) { + Log.w(TAG, "it seems that the note has not data"); + return; + } + while (c.moveToNext()) { + SqlData data = new SqlData(mContext, c); + mDataList.add(data); + } + } else { + Log.w(TAG, "loadDataContent: cursor = null"); + } + } finally { + if (c != null) + c.close(); + } + } + + public boolean setContent(JSONObject js) { + try { + JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { + Log.w(TAG, "cannot set system folder"); + } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { + // for folder we can only update the snnipet and type + String snippet = note.has(NoteColumns.SNIPPET) ? note + .getString(NoteColumns.SNIPPET) : ""; + if (mIsCreate || !mSnippet.equals(snippet)) { + mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); + } + mSnippet = snippet; + + int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) + : Notes.TYPE_NOTE; + if (mIsCreate || mType != type) { + mDiffNoteValues.put(NoteColumns.TYPE, type); + } + mType = type; + } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) { + JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); + long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID; + if (mIsCreate || mId != id) { + mDiffNoteValues.put(NoteColumns.ID, id); + } + mId = id; + + long alertDate = note.has(NoteColumns.ALERTED_DATE) ? note + .getLong(NoteColumns.ALERTED_DATE) : 0; + if (mIsCreate || mAlertDate != alertDate) { + mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate); + } + mAlertDate = alertDate; + + int bgColorId = note.has(NoteColumns.BG_COLOR_ID) ? note + .getInt(NoteColumns.BG_COLOR_ID) : ResourceParser.getDefaultBgId(mContext); + if (mIsCreate || mBgColorId != bgColorId) { + mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId); + } + mBgColorId = bgColorId; + + long createDate = note.has(NoteColumns.CREATED_DATE) ? note + .getLong(NoteColumns.CREATED_DATE) : System.currentTimeMillis(); + if (mIsCreate || mCreatedDate != createDate) { + mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate); + } + mCreatedDate = createDate; + + int hasAttachment = note.has(NoteColumns.HAS_ATTACHMENT) ? note + .getInt(NoteColumns.HAS_ATTACHMENT) : 0; + if (mIsCreate || mHasAttachment != hasAttachment) { + mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment); + } + mHasAttachment = hasAttachment; + + long modifiedDate = note.has(NoteColumns.MODIFIED_DATE) ? note + .getLong(NoteColumns.MODIFIED_DATE) : System.currentTimeMillis(); + if (mIsCreate || mModifiedDate != modifiedDate) { + mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate); + } + mModifiedDate = modifiedDate; + + long parentId = note.has(NoteColumns.PARENT_ID) ? note + .getLong(NoteColumns.PARENT_ID) : 0; + if (mIsCreate || mParentId != parentId) { + mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId); + } + mParentId = parentId; + + String snippet = note.has(NoteColumns.SNIPPET) ? note + .getString(NoteColumns.SNIPPET) : ""; + if (mIsCreate || !mSnippet.equals(snippet)) { + mDiffNoteValues.put(NoteColumns.SNIPPET, snippet); + } + mSnippet = snippet; + + int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) + : Notes.TYPE_NOTE; + if (mIsCreate || mType != type) { + mDiffNoteValues.put(NoteColumns.TYPE, type); + } + mType = type; + + int widgetId = note.has(NoteColumns.WIDGET_ID) ? note.getInt(NoteColumns.WIDGET_ID) + : AppWidgetManager.INVALID_APPWIDGET_ID; + if (mIsCreate || mWidgetId != widgetId) { + mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId); + } + mWidgetId = widgetId; + + int widgetType = note.has(NoteColumns.WIDGET_TYPE) ? note + .getInt(NoteColumns.WIDGET_TYPE) : Notes.TYPE_WIDGET_INVALIDE; + if (mIsCreate || mWidgetType != widgetType) { + mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType); + } + mWidgetType = widgetType; + + long originParent = note.has(NoteColumns.ORIGIN_PARENT_ID) ? note + .getLong(NoteColumns.ORIGIN_PARENT_ID) : 0; + if (mIsCreate || mOriginParent != originParent) { + mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent); + } + mOriginParent = originParent; + + for (int i = 0; i < dataArray.length(); i++) { + JSONObject data = dataArray.getJSONObject(i); + SqlData sqlData = null; + if (data.has(DataColumns.ID)) { + long dataId = data.getLong(DataColumns.ID); + for (SqlData temp : mDataList) { + if (dataId == temp.getId()) { + sqlData = temp; + } + } + } + + if (sqlData == null) { + sqlData = new SqlData(mContext); + mDataList.add(sqlData); + } + + sqlData.setContent(data); + } + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return false; + } + return true; + } + + public JSONObject getContent() { + try { + JSONObject js = new JSONObject(); + + if (mIsCreate) { + Log.e(TAG, "it seems that we haven't created this in database yet"); + return null; + } + + JSONObject note = new JSONObject(); + if (mType == Notes.TYPE_NOTE) { + note.put(NoteColumns.ID, mId); + note.put(NoteColumns.ALERTED_DATE, mAlertDate); + note.put(NoteColumns.BG_COLOR_ID, mBgColorId); + note.put(NoteColumns.CREATED_DATE, mCreatedDate); + note.put(NoteColumns.HAS_ATTACHMENT, mHasAttachment); + note.put(NoteColumns.MODIFIED_DATE, mModifiedDate); + note.put(NoteColumns.PARENT_ID, mParentId); + note.put(NoteColumns.SNIPPET, mSnippet); + note.put(NoteColumns.TYPE, mType); + note.put(NoteColumns.WIDGET_ID, mWidgetId); + note.put(NoteColumns.WIDGET_TYPE, mWidgetType); + note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent); + js.put(GTaskStringUtils.META_HEAD_NOTE, note); + + JSONArray dataArray = new JSONArray(); + for (SqlData sqlData : mDataList) { + JSONObject data = sqlData.getContent(); + if (data != null) { + dataArray.put(data); + } + } + js.put(GTaskStringUtils.META_HEAD_DATA, dataArray); + } else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) { + note.put(NoteColumns.ID, mId); + note.put(NoteColumns.TYPE, mType); + note.put(NoteColumns.SNIPPET, mSnippet); + js.put(GTaskStringUtils.META_HEAD_NOTE, note); + } + + return js; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + return null; + } + + public void setParentId(long id) { + mParentId = id; + mDiffNoteValues.put(NoteColumns.PARENT_ID, id); + } + + public void setGtaskId(String gid) { + mDiffNoteValues.put(NoteColumns.GTASK_ID, gid); + } + + public void setSyncId(long syncId) { + mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId); + } + + public void resetLocalModified() { + mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0); + } + + public long getId() { + return mId; + } + + public long getParentId() { + return mParentId; + } + + public String getSnippet() { + return mSnippet; + } + + public boolean isNoteType() { + return mType == Notes.TYPE_NOTE; + } + + public void commit(boolean validateVersion) { + if (mIsCreate) { + if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) { + mDiffNoteValues.remove(NoteColumns.ID); + } + + Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues); + try { + mId = Long.valueOf(uri.getPathSegments().get(1)); + } catch (NumberFormatException e) { + Log.e(TAG, "Get note id error :" + e.toString()); + throw new ActionFailureException("create note failed"); + } + if (mId == 0) { + throw new IllegalStateException("Create thread id failed"); + } + + if (mType == Notes.TYPE_NOTE) { + for (SqlData sqlData : mDataList) { + sqlData.commit(mId, false, -1); + } + } + } else { + if (mId <= 0 && mId != Notes.ID_ROOT_FOLDER && mId != Notes.ID_CALL_RECORD_FOLDER) { + Log.e(TAG, "No such note"); + throw new IllegalStateException("Try to update note with invalid id"); + } + if (mDiffNoteValues.size() > 0) { + mVersion ++; + int result = 0; + if (!validateVersion) { + result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "(" + + NoteColumns.ID + "=?)", new String[] { + String.valueOf(mId) + }); + } else { + result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "(" + + NoteColumns.ID + "=?) AND (" + NoteColumns.VERSION + "<=?)", + new String[] { + String.valueOf(mId), String.valueOf(mVersion) + }); + } + if (result == 0) { + Log.w(TAG, "there is no update. maybe user updates note when syncing"); + } + } + + if (mType == Notes.TYPE_NOTE) { + for (SqlData sqlData : mDataList) { + sqlData.commit(mId, validateVersion, mVersion); + } + } + } + + // refresh local info + loadFromCursor(mId); + if (mType == Notes.TYPE_NOTE) + loadDataContent(); + + mDiffNoteValues.clear(); + mIsCreate = false; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Task.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Task.java new file mode 100644 index 0000000..6a19454 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/Task.java @@ -0,0 +1,351 @@ +/* + * 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.database.Cursor; +import android.text.TextUtils; +import android.util.Log; + +import net.micode.notes.data.Notes; +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.gtask.exception.ActionFailureException; +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + + +public class Task extends Node { + private static final String TAG = Task.class.getSimpleName(); + + private boolean mCompleted; + + private String mNotes; + + private JSONObject mMetaInfo; + + private Task mPriorSibling; + + private TaskList mParent; + + public Task() { + super(); + mCompleted = false; + mNotes = null; + mPriorSibling = null; + mParent = null; + mMetaInfo = null; + } + + public JSONObject getCreateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // index + js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this)); + + // entity_delta + JSONObject entity = new JSONObject(); + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); + 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); + + // parent_id + js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid()); + + // dest_parent_type + js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE, + GTaskStringUtils.GTASK_JSON_TYPE_GROUP); + + // list_id + js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid()); + + // prior_sibling_id + if (mPriorSibling != null) { + js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid()); + } + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate task-create jsonobject"); + } + + return js; + } + + public JSONObject getUpdateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // id + js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); + + // entity_delta + 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) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate task-update jsonobject"); + } + + return js; + } + + public void setContentByRemoteJSON(JSONObject js) { + if (js != null) { + try { + // id + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { + setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); + } + + // last_modified + if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { + setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); + } + + // name + if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { + setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); + } + + // notes + if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) { + setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES)); + } + + // deleted + if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) { + setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED)); + } + + // completed + if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) { + setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED)); + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to get task content from jsonobject"); + } + } + } + + 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)) { + setName(data.getString(DataColumns.CONTENT)); + break; + } + } + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + } + + public JSONObject getLocalJSONFromContent() { + String name = getName(); + try { + if (mMetaInfo == null) { + // new task created from web + if (name == null) { + Log.w(TAG, "the note seems to be an empty one"); + return null; + } + + JSONObject js = new JSONObject(); + 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; + } else { + // synced task + 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) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return null; + } + } + + public void setMetaInfo(MetaData metaData) { + if (metaData != null && metaData.getNotes() != null) { + try { + mMetaInfo = new JSONObject(metaData.getNotes()); + } catch (JSONException e) { + Log.w(TAG, e.toString()); + mMetaInfo = 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)) { + Log.w(TAG, "remote note id seems to be deleted"); + return SYNC_ACTION_UPDATE_LOCAL; + } + + // validate the note id now + 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) { + // there is no local update + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { + // no update both side + return SYNC_ACTION_NONE; + } else { + // apply remote to local + return SYNC_ACTION_UPDATE_LOCAL; + } + } else { + // validate 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()) { + // local modification only + 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; + } + +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/TaskList.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/TaskList.java new file mode 100644 index 0000000..4ea21c5 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/data/TaskList.java @@ -0,0 +1,343 @@ +/* + * 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.database.Cursor; +import android.util.Log; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + + +public class TaskList extends Node { + private static final String TAG = TaskList.class.getSimpleName(); + + private int mIndex; + + private ArrayList mChildren; + + public TaskList() { + super(); + mChildren = new ArrayList(); + mIndex = 1; + } + + public JSONObject getCreateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // index + js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex); + + // entity_delta + JSONObject entity = new JSONObject(); + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); + entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, + GTaskStringUtils.GTASK_JSON_TYPE_GROUP); + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate tasklist-create jsonobject"); + } + + return js; + } + + public JSONObject getUpdateAction(int actionId) { + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); + + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // id + js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); + + // entity_delta + JSONObject entity = new JSONObject(); + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate tasklist-update jsonobject"); + } + + return js; + } + + public void setContentByRemoteJSON(JSONObject js) { + if (js != null) { + try { + // id + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { + setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); + } + + // last_modified + if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { + setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); + } + + // name + if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { + setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); + } + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to get tasklist content from jsonobject"); + } + } + } + + public void setContentByLocalJSON(JSONObject js) { + if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { + Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); + } + + try { + JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + + if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { + String name = folder.getString(NoteColumns.SNIPPET); + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name); + } else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { + if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER) + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT); + else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER) + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_CALL_NOTE); + else + Log.e(TAG, "invalid system folder"); + } else { + Log.e(TAG, "error type"); + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + } + + public JSONObject getLocalJSONFromContent() { + try { + JSONObject js = new JSONObject(); + JSONObject folder = new JSONObject(); + + String folderName = getName(); + if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX)) + folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(), + folderName.length()); + folder.put(NoteColumns.SNIPPET, folderName); + if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT) + || folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE)) + folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + else + folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + + js.put(GTaskStringUtils.META_HEAD_NOTE, folder); + + return js; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return null; + } + } + + public int getSyncAction(Cursor c) { + try { + if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { + // there is no local update + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { + // no update both side + return SYNC_ACTION_NONE; + } else { + // apply remote to local + return SYNC_ACTION_UPDATE_LOCAL; + } + } else { + // validate 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()) { + // local modification only + return SYNC_ACTION_UPDATE_REMOTE; + } else { + // for folder conflicts, just apply local modification + return SYNC_ACTION_UPDATE_REMOTE; + } + } + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + + return SYNC_ACTION_ERROR; + } + + public int getChildTaskCount() { + return mChildren.size(); + } + + public boolean addChildTask(Task task) { + boolean ret = false; + if (task != null && !mChildren.contains(task)) { + ret = mChildren.add(task); + if (ret) { + // need to set prior sibling and parent + task.setPriorSibling(mChildren.isEmpty() ? null : mChildren + .get(mChildren.size() - 1)); + task.setParent(this); + } + } + return ret; + } + + public boolean addChildTask(Task task, int index) { + if (index < 0 || index > mChildren.size()) { + Log.e(TAG, "add child task: invalid index"); + return false; + } + + int pos = mChildren.indexOf(task); + if (task != null && pos == -1) { + mChildren.add(index, task); + + // update the task list + Task preTask = null; + Task afterTask = null; + if (index != 0) + preTask = mChildren.get(index - 1); + if (index != mChildren.size() - 1) + afterTask = mChildren.get(index + 1); + + task.setPriorSibling(preTask); + if (afterTask != null) + afterTask.setPriorSibling(task); + } + + return true; + } + + public boolean removeChildTask(Task task) { + boolean ret = false; + int index = mChildren.indexOf(task); + if (index != -1) { + ret = mChildren.remove(task); + + if (ret) { + // reset prior sibling and parent + task.setPriorSibling(null); + task.setParent(null); + + // update the task list + if (index != mChildren.size()) { + mChildren.get(index).setPriorSibling( + index == 0 ? null : mChildren.get(index - 1)); + } + } + } + return ret; + } + + public boolean moveChildTask(Task task, int index) { + + if (index < 0 || index >= mChildren.size()) { + Log.e(TAG, "move child task: invalid index"); + return false; + } + + int pos = mChildren.indexOf(task); + if (pos == -1) { + Log.e(TAG, "move child task: the task should in the list"); + return false; + } + + if (pos == index) + return true; + return (removeChildTask(task) && addChildTask(task, index)); + } + + public Task findChildTaskByGid(String gid) { + for (int i = 0; i < mChildren.size(); i++) { + Task t = mChildren.get(i); + if (t.getGid().equals(gid)) { + return t; + } + } + return null; + } + + public int getChildTaskIndex(Task task) { + return mChildren.indexOf(task); + } + + public Task getChildTaskByIndex(int index) { + if (index < 0 || index >= mChildren.size()) { + Log.e(TAG, "getTaskByIndex: invalid index"); + return null; + } + return mChildren.get(index); + } + + public Task getChilTaskByGid(String gid) { + for (Task task : mChildren) { + if (task.getGid().equals(gid)) + return task; + } + return null; + } + + public ArrayList getChildTaskList() { + return this.mChildren; + } + + public void setIndex(int index) { + this.mIndex = index; + } + + public int getIndex() { + return this.mIndex; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/ActionFailureException.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/ActionFailureException.java new file mode 100644 index 0000000..15504be --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/ActionFailureException.java @@ -0,0 +1,33 @@ +/* + * 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.exception; + +public class ActionFailureException extends RuntimeException { + private static final long serialVersionUID = 4425249765923293627L; + + public ActionFailureException() { + super(); + } + + public ActionFailureException(String paramString) { + super(paramString); + } + + public ActionFailureException(String paramString, Throwable paramThrowable) { + super(paramString, paramThrowable); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/NetworkFailureException.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/NetworkFailureException.java new file mode 100644 index 0000000..b08cfb1 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/exception/NetworkFailureException.java @@ -0,0 +1,33 @@ +/* + * 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.exception; + +public class NetworkFailureException extends Exception { + private static final long serialVersionUID = 2107610287180234136L; + + public NetworkFailureException() { + super(); + } + + public NetworkFailureException(String paramString) { + super(paramString); + } + + public NetworkFailureException(String paramString, Throwable paramThrowable) { + super(paramString, paramThrowable); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskASyncTask.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskASyncTask.java new file mode 100644 index 0000000..1f280dc --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskASyncTask.java @@ -0,0 +1,143 @@ + +/* + * 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.remote; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; + +import net.micode.notes.R; +import net.micode.notes.ui.NotesListActivity; +import net.micode.notes.ui.NotesPreferenceActivity; + + +public class GTaskASyncTask extends AsyncTask { + + private static int GTASK_SYNC_NOTIFICATION_ID = 5234235; + + public interface OnCompleteListener { + void onComplete(); + } + + private Context mContext; + + private NotificationManager mNotifiManager; + + private GTaskManager mTaskManager; + + private OnCompleteListener mOnCompleteListener; + + public GTaskASyncTask(Context context, OnCompleteListener listener) { + mContext = context; + mOnCompleteListener = listener; + mNotifiManager = (NotificationManager) mContext + .getSystemService(Context.NOTIFICATION_SERVICE); + mTaskManager = GTaskManager.getInstance(); + } + + public void cancelSync() { + mTaskManager.cancelSync(); + } + + public void publishProgess(String message) { + publishProgress(new String[] { + message + }); + } + +// private void showNotification(int tickerId, String content) { +// Notification notification = new Notification(R.drawable.notification, mContext + // .getString(tickerId), System.currentTimeMillis()); +// notification.defaults = Notification.DEFAULT_LIGHTS; +// notification.flags = Notification.FLAG_AUTO_CANCEL; + // PendingIntent pendingIntent; + // if (tickerId != R.string.ticker_success) { + // pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + // NotesPreferenceActivity.class), 0); +// + // } else { + // pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, +// NotesListActivity.class), 0); + // } + // notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content, + // pendingIntent); + // mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification); + // } +private void showNotification(int tickerId, String content) { + PendingIntent pendingIntent; + if (tickerId != R.string.ticker_success) { + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + NotesPreferenceActivity.class), PendingIntent.FLAG_IMMUTABLE); + } else { + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + NotesListActivity.class), PendingIntent.FLAG_IMMUTABLE); + } + Notification.Builder builder = new Notification.Builder(mContext) + .setAutoCancel(true) + .setContentTitle(mContext.getString(R.string.app_name)) + .setContentText(content) + .setContentIntent(pendingIntent) + .setWhen(System.currentTimeMillis()) + .setOngoing(true); + Notification notification=builder.getNotification(); + mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification); +} + + + @Override + protected Integer doInBackground(Void... unused) { + publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity + .getSyncAccountName(mContext))); + return mTaskManager.sync(mContext, this); + } + + @Override + protected void onProgressUpdate(String... progress) { + showNotification(R.string.ticker_syncing, progress[0]); + if (mContext instanceof GTaskSyncService) { + ((GTaskSyncService) mContext).sendBroadcast(progress[0]); + } + } + + @Override + protected void onPostExecute(Integer result) { + if (result == GTaskManager.STATE_SUCCESS) { + showNotification(R.string.ticker_success, mContext.getString( + R.string.success_sync_account, mTaskManager.getSyncAccount())); + NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis()); + } else if (result == GTaskManager.STATE_NETWORK_ERROR) { + showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_network)); + } else if (result == GTaskManager.STATE_INTERNAL_ERROR) { + showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_internal)); + } else if (result == GTaskManager.STATE_SYNC_CANCELLED) { + showNotification(R.string.ticker_cancel, mContext + .getString(R.string.error_sync_cancelled)); + } + if (mOnCompleteListener != null) { + new Thread(new Runnable() { + + public void run() { + mOnCompleteListener.onComplete(); + } + }).start(); + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskClient.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskClient.java new file mode 100644 index 0000000..c67dfdf --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskClient.java @@ -0,0 +1,585 @@ +/* + * 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.remote; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerFuture; +import android.app.Activity; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; + +import net.micode.notes.gtask.data.Node; +import net.micode.notes.gtask.data.Task; +import net.micode.notes.gtask.data.TaskList; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.gtask.exception.NetworkFailureException; +import net.micode.notes.tool.GTaskStringUtils; +import net.micode.notes.ui.NotesPreferenceActivity; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.cookie.Cookie; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.LinkedList; +import java.util.List; +import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + + +public class GTaskClient { + private static final String TAG = GTaskClient.class.getSimpleName(); + + private static final String GTASK_URL = "https://mail.google.com/tasks/"; + + private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig"; + + private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig"; + + private static GTaskClient mInstance = null; + + private DefaultHttpClient mHttpClient; + + private String mGetUrl; + + private String mPostUrl; + + private long mClientVersion; + + private boolean mLoggedin; + + private long mLastLoginTime; + + private int mActionId; + + private Account mAccount; + + private JSONArray mUpdateArray; + + private GTaskClient() { + mHttpClient = null; + mGetUrl = GTASK_GET_URL; + mPostUrl = GTASK_POST_URL; + mClientVersion = -1; + mLoggedin = false; + mLastLoginTime = 0; + mActionId = 1; + mAccount = null; + mUpdateArray = null; + } + + public static synchronized GTaskClient getInstance() { + if (mInstance == null) { + mInstance = new GTaskClient(); + } + return mInstance; + } + + public boolean login(Activity activity) { + // we suppose that the cookie would expire after 5 minutes + // then we need to re-login + final long interval = 1000 * 60 * 5; + if (mLastLoginTime + interval < System.currentTimeMillis()) { + mLoggedin = false; + } + + // need to re-login after account switch + if (mLoggedin + && !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity + .getSyncAccountName(activity))) { + mLoggedin = false; + } + + if (mLoggedin) { + Log.d(TAG, "already logged in"); + return true; + } + + mLastLoginTime = System.currentTimeMillis(); + String authToken = loginGoogleAccount(activity, false); + if (authToken == null) { + Log.e(TAG, "login google account failed"); + return false; + } + + // login with custom domain if necessary + if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() + .endsWith("googlemail.com"))) { + StringBuilder url = new StringBuilder(GTASK_URL).append("a/"); + int index = mAccount.name.indexOf('@') + 1; + String suffix = mAccount.name.substring(index); + url.append(suffix + "/"); + mGetUrl = url.toString() + "ig"; + mPostUrl = url.toString() + "r/ig"; + + if (tryToLoginGtask(activity, authToken)) { + mLoggedin = true; + } + } + + // try to login with google official url + if (!mLoggedin) { + mGetUrl = GTASK_GET_URL; + mPostUrl = GTASK_POST_URL; + if (!tryToLoginGtask(activity, authToken)) { + return false; + } + } + + mLoggedin = true; + return true; + } + + private String loginGoogleAccount(Activity activity, boolean invalidateToken) { + String authToken; + AccountManager accountManager = AccountManager.get(activity); + Account[] accounts = accountManager.getAccountsByType("com.google"); + + if (accounts.length == 0) { + Log.e(TAG, "there is no available google account"); + return null; + } + + String accountName = NotesPreferenceActivity.getSyncAccountName(activity); + Account account = null; + for (Account a : accounts) { + if (a.name.equals(accountName)) { + account = a; + break; + } + } + if (account != null) { + mAccount = account; + } else { + Log.e(TAG, "unable to get an account with the same name in the settings"); + return null; + } + + // get the token now + AccountManagerFuture accountManagerFuture = accountManager.getAuthToken(account, + "goanna_mobile", null, activity, null, null); + try { + Bundle authTokenBundle = accountManagerFuture.getResult(); + authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN); + if (invalidateToken) { + accountManager.invalidateAuthToken("com.google", authToken); + loginGoogleAccount(activity, false); + } + } catch (Exception e) { + Log.e(TAG, "get auth token failed"); + authToken = null; + } + + return authToken; + } + + private boolean tryToLoginGtask(Activity activity, String authToken) { + if (!loginGtask(authToken)) { + // maybe the auth token is out of date, now let's invalidate the + // token and try again + authToken = loginGoogleAccount(activity, true); + if (authToken == null) { + Log.e(TAG, "login google account failed"); + return false; + } + + if (!loginGtask(authToken)) { + Log.e(TAG, "login gtask failed"); + return false; + } + } + return true; + } + + private boolean loginGtask(String authToken) { + int timeoutConnection = 10000; + int timeoutSocket = 15000; + HttpParams httpParameters = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); + HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); + mHttpClient = new DefaultHttpClient(httpParameters); + BasicCookieStore localBasicCookieStore = new BasicCookieStore(); + mHttpClient.setCookieStore(localBasicCookieStore); + HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); + + // login gtask + try { + String loginUrl = mGetUrl + "?auth=" + authToken; + HttpGet httpGet = new HttpGet(loginUrl); + HttpResponse response = null; + response = mHttpClient.execute(httpGet); + + // get the cookie now + List cookies = mHttpClient.getCookieStore().getCookies(); + boolean hasAuthCookie = false; + for (Cookie cookie : cookies) { + if (cookie.getName().contains("GTL")) { + hasAuthCookie = true; + } + } + if (!hasAuthCookie) { + Log.w(TAG, "it seems that there is no auth cookie"); + } + + // get the client version + String resString = getResponseContent(response.getEntity()); + String jsBegin = "_setup("; + String jsEnd = ")}"; + int begin = resString.indexOf(jsBegin); + int end = resString.lastIndexOf(jsEnd); + String jsString = null; + if (begin != -1 && end != -1 && begin < end) { + jsString = resString.substring(begin + jsBegin.length(), end); + } + JSONObject js = new JSONObject(jsString); + mClientVersion = js.getLong("v"); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return false; + } catch (Exception e) { + // simply catch all exceptions + Log.e(TAG, "httpget gtask_url failed"); + return false; + } + + return true; + } + + private int getActionId() { + return mActionId++; + } + + private HttpPost createHttpPost() { + HttpPost httpPost = new HttpPost(mPostUrl); + httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); + httpPost.setHeader("AT", "1"); + return httpPost; + } + + private String getResponseContent(HttpEntity entity) throws IOException { + String contentEncoding = null; + if (entity.getContentEncoding() != null) { + contentEncoding = entity.getContentEncoding().getValue(); + Log.d(TAG, "encoding: " + contentEncoding); + } + + InputStream input = entity.getContent(); + if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { + input = new GZIPInputStream(entity.getContent()); + } else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) { + Inflater inflater = new Inflater(true); + input = new InflaterInputStream(entity.getContent(), inflater); + } + + try { + InputStreamReader isr = new InputStreamReader(input); + BufferedReader br = new BufferedReader(isr); + StringBuilder sb = new StringBuilder(); + + while (true) { + String buff = br.readLine(); + if (buff == null) { + return sb.toString(); + } + sb = sb.append(buff); + } + } finally { + input.close(); + } + } + + private JSONObject postRequest(JSONObject js) throws NetworkFailureException { + if (!mLoggedin) { + Log.e(TAG, "please login first"); + throw new ActionFailureException("not logged in"); + } + + HttpPost httpPost = createHttpPost(); + try { + LinkedList list = new LinkedList(); + list.add(new BasicNameValuePair("r", js.toString())); + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8"); + httpPost.setEntity(entity); + + // execute the post + HttpResponse response = mHttpClient.execute(httpPost); + String jsString = getResponseContent(response.getEntity()); + return new JSONObject(jsString); + + } catch (ClientProtocolException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("postRequest failed"); + } catch (IOException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("postRequest failed"); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("unable to convert response content to jsonobject"); + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("error occurs when posting request"); + } + } + + public void createTask(Task task) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + + // action_list + actionList.put(task.getCreateAction(getActionId())); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + // post + JSONObject jsResponse = postRequest(jsPost); + JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( + GTaskStringUtils.GTASK_JSON_RESULTS).get(0); + task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("create task: handing jsonobject failed"); + } + } + + public void createTaskList(TaskList tasklist) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + + // action_list + actionList.put(tasklist.getCreateAction(getActionId())); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + // post + JSONObject jsResponse = postRequest(jsPost); + JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( + GTaskStringUtils.GTASK_JSON_RESULTS).get(0); + tasklist.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("create tasklist: handing jsonobject failed"); + } + } + + public void commitUpdate() throws NetworkFailureException { + if (mUpdateArray != null) { + try { + JSONObject jsPost = new JSONObject(); + + // action_list + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + postRequest(jsPost); + mUpdateArray = null; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("commit update: handing jsonobject failed"); + } + } + } + + public void addUpdateNode(Node node) throws NetworkFailureException { + if (node != null) { + // too many update items may result in an error + // set max to 10 items + if (mUpdateArray != null && mUpdateArray.length() > 10) { + commitUpdate(); + } + + if (mUpdateArray == null) + mUpdateArray = new JSONArray(); + mUpdateArray.put(node.getUpdateAction(getActionId())); + } + } + + public void moveTask(Task task, TaskList preParent, TaskList curParent) + throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + JSONObject action = new JSONObject(); + + // action_list + action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE); + action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); + action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid()); + if (preParent == curParent && task.getPriorSibling() != null) { + // put prioring_sibing_id only if moving within the tasklist and + // it is not the first one + action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling()); + } + action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid()); + action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid()); + if (preParent != curParent) { + // put the dest_list only if moving between tasklists + action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid()); + } + actionList.put(action); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + postRequest(jsPost); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("move task: handing jsonobject failed"); + } + } + + public void deleteNode(Node node) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + + // action_list + node.setDeleted(true); + actionList.put(node.getUpdateAction(getActionId())); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + postRequest(jsPost); + mUpdateArray = null; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("delete node: handing jsonobject failed"); + } + } + + public JSONArray getTaskLists() throws NetworkFailureException { + if (!mLoggedin) { + Log.e(TAG, "please login first"); + throw new ActionFailureException("not logged in"); + } + + try { + HttpGet httpGet = new HttpGet(mGetUrl); + HttpResponse response = null; + response = mHttpClient.execute(httpGet); + + // get the task list + String resString = getResponseContent(response.getEntity()); + String jsBegin = "_setup("; + String jsEnd = ")}"; + int begin = resString.indexOf(jsBegin); + int end = resString.lastIndexOf(jsEnd); + String jsString = null; + if (begin != -1 && end != -1 && begin < end) { + jsString = resString.substring(begin + jsBegin.length(), end); + } + JSONObject js = new JSONObject(jsString); + return js.getJSONObject("t").getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS); + } catch (ClientProtocolException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("gettasklists: httpget failed"); + } catch (IOException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new NetworkFailureException("gettasklists: httpget failed"); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("get task lists: handing jasonobject failed"); + } + } + + public JSONArray getTaskList(String listGid) throws NetworkFailureException { + commitUpdate(); + try { + JSONObject jsPost = new JSONObject(); + JSONArray actionList = new JSONArray(); + JSONObject action = new JSONObject(); + + // action_list + action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL); + action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); + action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid); + action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, false); + actionList.put(action); + jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); + + // client_version + jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); + + JSONObject jsResponse = postRequest(jsPost); + return jsResponse.getJSONArray(GTaskStringUtils.GTASK_JSON_TASKS); + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("get task list: handing jsonobject failed"); + } + } + + public Account getSyncAccount() { + return mAccount; + } + + public void resetUpdateArray() { + mUpdateArray = null; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskManager.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskManager.java new file mode 100644 index 0000000..d2b4082 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskManager.java @@ -0,0 +1,800 @@ +/* + * 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.remote; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.util.Log; + +import net.micode.notes.R; +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.data.MetaData; +import net.micode.notes.gtask.data.Node; +import net.micode.notes.gtask.data.SqlNote; +import net.micode.notes.gtask.data.Task; +import net.micode.notes.gtask.data.TaskList; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.gtask.exception.NetworkFailureException; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + + +public class GTaskManager { + private static final String TAG = GTaskManager.class.getSimpleName(); + + public static final int STATE_SUCCESS = 0; + + public static final int STATE_NETWORK_ERROR = 1; + + public static final int STATE_INTERNAL_ERROR = 2; + + public static final int STATE_SYNC_IN_PROGRESS = 3; + + public static final int STATE_SYNC_CANCELLED = 4; + + private static GTaskManager mInstance = null; + + private Activity mActivity; + + private Context mContext; + + private ContentResolver mContentResolver; + + private boolean mSyncing; + + private boolean mCancelled; + + private HashMap mGTaskListHashMap; + + private HashMap mGTaskHashMap; + + private HashMap mMetaHashMap; + + private TaskList mMetaList; + + private HashSet mLocalDeleteIdMap; + + private HashMap mGidToNid; + + private HashMap mNidToGid; + + private GTaskManager() { + mSyncing = false; + mCancelled = false; + mGTaskListHashMap = new HashMap(); + mGTaskHashMap = new HashMap(); + mMetaHashMap = new HashMap(); + mMetaList = null; + mLocalDeleteIdMap = new HashSet(); + mGidToNid = new HashMap(); + mNidToGid = new HashMap(); + } + + public static synchronized GTaskManager getInstance() { + if (mInstance == null) { + mInstance = new GTaskManager(); + } + return mInstance; + } + + public synchronized void setActivityContext(Activity activity) { + // used for getting authtoken + mActivity = activity; + } + + public int sync(Context context, GTaskASyncTask asyncTask) { + if (mSyncing) { + Log.d(TAG, "Sync is in progress"); + return STATE_SYNC_IN_PROGRESS; + } + mContext = context; + mContentResolver = mContext.getContentResolver(); + mSyncing = true; + mCancelled = false; + mGTaskListHashMap.clear(); + mGTaskHashMap.clear(); + mMetaHashMap.clear(); + mLocalDeleteIdMap.clear(); + mGidToNid.clear(); + mNidToGid.clear(); + + try { + GTaskClient client = GTaskClient.getInstance(); + client.resetUpdateArray(); + + // login google task + if (!mCancelled) { + if (!client.login(mActivity)) { + throw new NetworkFailureException("login google task failed"); + } + } + + // get the task list from google + asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list)); + initGTaskList(); + + // do content sync work + asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing)); + syncContent(); + } catch (NetworkFailureException e) { + Log.e(TAG, e.toString()); + return STATE_NETWORK_ERROR; + } catch (ActionFailureException e) { + Log.e(TAG, e.toString()); + return STATE_INTERNAL_ERROR; + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return STATE_INTERNAL_ERROR; + } finally { + mGTaskListHashMap.clear(); + mGTaskHashMap.clear(); + mMetaHashMap.clear(); + mLocalDeleteIdMap.clear(); + mGidToNid.clear(); + mNidToGid.clear(); + mSyncing = false; + } + + return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS; + } + + private void initGTaskList() throws NetworkFailureException { + if (mCancelled) + return; + GTaskClient client = GTaskClient.getInstance(); + try { + JSONArray jsTaskLists = client.getTaskLists(); + + // init meta list first + mMetaList = null; + for (int i = 0; i < jsTaskLists.length(); i++) { + JSONObject object = jsTaskLists.getJSONObject(i); + String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); + String name = object.getString(GTaskStringUtils.GTASK_JSON_NAME); + + if (name + .equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_META)) { + mMetaList = new TaskList(); + mMetaList.setContentByRemoteJSON(object); + + // load meta data + JSONArray jsMetas = client.getTaskList(gid); + for (int j = 0; j < jsMetas.length(); j++) { + object = (JSONObject) jsMetas.getJSONObject(j); + MetaData metaData = new MetaData(); + metaData.setContentByRemoteJSON(object); + if (metaData.isWorthSaving()) { + mMetaList.addChildTask(metaData); + if (metaData.getGid() != null) { + mMetaHashMap.put(metaData.getRelatedGid(), metaData); + } + } + } + } + } + + // create meta list if not existed + if (mMetaList == null) { + mMetaList = new TaskList(); + mMetaList.setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_META); + GTaskClient.getInstance().createTaskList(mMetaList); + } + + // init task list + for (int i = 0; i < jsTaskLists.length(); i++) { + JSONObject object = jsTaskLists.getJSONObject(i); + String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); + String name = object.getString(GTaskStringUtils.GTASK_JSON_NAME); + + if (name.startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX) + && !name.equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_META)) { + TaskList tasklist = new TaskList(); + tasklist.setContentByRemoteJSON(object); + mGTaskListHashMap.put(gid, tasklist); + mGTaskHashMap.put(gid, tasklist); + + // load tasks + JSONArray jsTasks = client.getTaskList(gid); + for (int j = 0; j < jsTasks.length(); j++) { + object = (JSONObject) jsTasks.getJSONObject(j); + gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); + Task task = new Task(); + task.setContentByRemoteJSON(object); + if (task.isWorthSaving()) { + task.setMetaInfo(mMetaHashMap.get(gid)); + tasklist.addChildTask(task); + mGTaskHashMap.put(gid, task); + } + } + } + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("initGTaskList: handing JSONObject failed"); + } + } + + private void syncContent() throws NetworkFailureException { + int syncType; + Cursor c = null; + String gid; + Node node; + + mLocalDeleteIdMap.clear(); + + if (mCancelled) { + return; + } + + // for local deleted note + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type<>? AND parent_id=?)", new String[] { + String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER) + }, null); + if (c != null) { + while (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + doContentSync(Node.SYNC_ACTION_DEL_REMOTE, node, c); + } + + mLocalDeleteIdMap.add(c.getLong(SqlNote.ID_COLUMN)); + } + } else { + Log.w(TAG, "failed to query trash folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // sync folder first + syncFolder(); + + // for note existing in database + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type=? AND parent_id<>?)", new String[] { + String.valueOf(Notes.TYPE_NOTE), String.valueOf(Notes.ID_TRASH_FOLER) + }, NoteColumns.TYPE + " DESC"); + if (c != null) { + while (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, c.getLong(SqlNote.ID_COLUMN)); + mNidToGid.put(c.getLong(SqlNote.ID_COLUMN), gid); + syncType = node.getSyncAction(c); + } else { + if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { + // local add + syncType = Node.SYNC_ACTION_ADD_REMOTE; + } else { + // remote delete + syncType = Node.SYNC_ACTION_DEL_LOCAL; + } + } + doContentSync(syncType, node, c); + } + } else { + Log.w(TAG, "failed to query existing note in database"); + } + + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // go through remaining items + Iterator> iter = mGTaskHashMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + node = entry.getValue(); + doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); + } + + // mCancelled can be set by another thread, so we neet to check one by + // one + // clear local delete table + if (!mCancelled) { + if (!DataUtils.batchDeleteNotes(mContentResolver, mLocalDeleteIdMap)) { + throw new ActionFailureException("failed to batch-delete local deleted notes"); + } + } + + // refresh local sync id + if (!mCancelled) { + GTaskClient.getInstance().commitUpdate(); + refreshLocalSyncId(); + } + + } + + private void syncFolder() throws NetworkFailureException { + Cursor c = null; + String gid; + Node node; + int syncType; + + if (mCancelled) { + return; + } + + // for root folder + try { + c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, + Notes.ID_ROOT_FOLDER), SqlNote.PROJECTION_NOTE, null, null, null); + if (c != null) { + c.moveToNext(); + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, (long) Notes.ID_ROOT_FOLDER); + mNidToGid.put((long) Notes.ID_ROOT_FOLDER, gid); + // for system folder, only update remote name if necessary + if (!node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) + doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); + } else { + doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c); + } + } else { + Log.w(TAG, "failed to query root folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // for call-note folder + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)", + new String[] { + String.valueOf(Notes.ID_CALL_RECORD_FOLDER) + }, null); + if (c != null) { + if (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, (long) Notes.ID_CALL_RECORD_FOLDER); + mNidToGid.put((long) Notes.ID_CALL_RECORD_FOLDER, gid); + // for system folder, only update remote name if + // necessary + if (!node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_CALL_NOTE)) + doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); + } else { + doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c); + } + } + } else { + Log.w(TAG, "failed to query call note folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // for local existing folders + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type=? AND parent_id<>?)", new String[] { + String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER) + }, NoteColumns.TYPE + " DESC"); + if (c != null) { + while (c.moveToNext()) { + gid = c.getString(SqlNote.GTASK_ID_COLUMN); + node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + mGidToNid.put(gid, c.getLong(SqlNote.ID_COLUMN)); + mNidToGid.put(c.getLong(SqlNote.ID_COLUMN), gid); + syncType = node.getSyncAction(c); + } else { + if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { + // local add + syncType = Node.SYNC_ACTION_ADD_REMOTE; + } else { + // remote delete + syncType = Node.SYNC_ACTION_DEL_LOCAL; + } + } + doContentSync(syncType, node, c); + } + } else { + Log.w(TAG, "failed to query existing folder"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + + // for remote add folders + Iterator> iter = mGTaskListHashMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + gid = entry.getKey(); + node = entry.getValue(); + if (mGTaskHashMap.containsKey(gid)) { + mGTaskHashMap.remove(gid); + doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); + } + } + + if (!mCancelled) + GTaskClient.getInstance().commitUpdate(); + } + + private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + MetaData meta; + switch (syncType) { + case Node.SYNC_ACTION_ADD_LOCAL: + addLocalNode(node); + break; + case Node.SYNC_ACTION_ADD_REMOTE: + addRemoteNode(node, c); + break; + case Node.SYNC_ACTION_DEL_LOCAL: + meta = mMetaHashMap.get(c.getString(SqlNote.GTASK_ID_COLUMN)); + if (meta != null) { + GTaskClient.getInstance().deleteNode(meta); + } + mLocalDeleteIdMap.add(c.getLong(SqlNote.ID_COLUMN)); + break; + case Node.SYNC_ACTION_DEL_REMOTE: + meta = mMetaHashMap.get(node.getGid()); + if (meta != null) { + GTaskClient.getInstance().deleteNode(meta); + } + GTaskClient.getInstance().deleteNode(node); + break; + case Node.SYNC_ACTION_UPDATE_LOCAL: + updateLocalNode(node, c); + break; + case Node.SYNC_ACTION_UPDATE_REMOTE: + updateRemoteNode(node, c); + break; + case Node.SYNC_ACTION_UPDATE_CONFLICT: + // merging both modifications maybe a good idea + // right now just use local update simply + updateRemoteNode(node, c); + break; + case Node.SYNC_ACTION_NONE: + break; + case Node.SYNC_ACTION_ERROR: + default: + throw new ActionFailureException("unkown sync action type"); + } + } + + private void addLocalNode(Node node) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote; + if (node instanceof TaskList) { + if (node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) { + sqlNote = new SqlNote(mContext, Notes.ID_ROOT_FOLDER); + } else if (node.getName().equals( + GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) { + sqlNote = new SqlNote(mContext, Notes.ID_CALL_RECORD_FOLDER); + } else { + sqlNote = new SqlNote(mContext); + sqlNote.setContent(node.getLocalJSONFromContent()); + sqlNote.setParentId(Notes.ID_ROOT_FOLDER); + } + } else { + sqlNote = new SqlNote(mContext); + JSONObject js = node.getLocalJSONFromContent(); + try { + if (js.has(GTaskStringUtils.META_HEAD_NOTE)) { + JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + if (note.has(NoteColumns.ID)) { + long id = note.getLong(NoteColumns.ID); + if (DataUtils.existInNoteDatabase(mContentResolver, id)) { + // the id is not available, have to create a new one + note.remove(NoteColumns.ID); + } + } + } + + if (js.has(GTaskStringUtils.META_HEAD_DATA)) { + JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); + for (int i = 0; i < dataArray.length(); i++) { + JSONObject data = dataArray.getJSONObject(i); + if (data.has(DataColumns.ID)) { + long dataId = data.getLong(DataColumns.ID); + if (DataUtils.existInDataDatabase(mContentResolver, dataId)) { + // the data id is not available, have to create + // a new one + data.remove(DataColumns.ID); + } + } + } + + } + } catch (JSONException e) { + Log.w(TAG, e.toString()); + e.printStackTrace(); + } + sqlNote.setContent(js); + + Long parentId = mGidToNid.get(((Task) node).getParent().getGid()); + if (parentId == null) { + Log.e(TAG, "cannot find task's parent id locally"); + throw new ActionFailureException("cannot add local node"); + } + sqlNote.setParentId(parentId.longValue()); + } + + // create the local node + sqlNote.setGtaskId(node.getGid()); + sqlNote.commit(false); + + // update gid-nid mapping + mGidToNid.put(node.getGid(), sqlNote.getId()); + mNidToGid.put(sqlNote.getId(), node.getGid()); + + // update meta + updateRemoteMeta(node.getGid(), sqlNote); + } + + private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote; + // update the note locally + sqlNote = new SqlNote(mContext, c); + sqlNote.setContent(node.getLocalJSONFromContent()); + + Long parentId = (node instanceof Task) ? mGidToNid.get(((Task) node).getParent().getGid()) + : new Long(Notes.ID_ROOT_FOLDER); + if (parentId == null) { + Log.e(TAG, "cannot find task's parent id locally"); + throw new ActionFailureException("cannot update local node"); + } + sqlNote.setParentId(parentId.longValue()); + sqlNote.commit(true); + + // update meta info + updateRemoteMeta(node.getGid(), sqlNote); + } + + private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote = new SqlNote(mContext, c); + Node n; + + // update remotely + if (sqlNote.isNoteType()) { + Task task = new Task(); + task.setContentByLocalJSON(sqlNote.getContent()); + + String parentGid = mNidToGid.get(sqlNote.getParentId()); + if (parentGid == null) { + Log.e(TAG, "cannot find task's parent tasklist"); + throw new ActionFailureException("cannot add remote task"); + } + mGTaskListHashMap.get(parentGid).addChildTask(task); + + GTaskClient.getInstance().createTask(task); + n = (Node) task; + + // add meta + updateRemoteMeta(task.getGid(), sqlNote); + } else { + TaskList tasklist = null; + + // we need to skip folder if it has already existed + String folderName = GTaskStringUtils.MIUI_FOLDER_PREFFIX; + if (sqlNote.getId() == Notes.ID_ROOT_FOLDER) + folderName += GTaskStringUtils.FOLDER_DEFAULT; + else if (sqlNote.getId() == Notes.ID_CALL_RECORD_FOLDER) + folderName += GTaskStringUtils.FOLDER_CALL_NOTE; + else + folderName += sqlNote.getSnippet(); + + Iterator> iter = mGTaskListHashMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + String gid = entry.getKey(); + TaskList list = entry.getValue(); + + if (list.getName().equals(folderName)) { + tasklist = list; + if (mGTaskHashMap.containsKey(gid)) { + mGTaskHashMap.remove(gid); + } + break; + } + } + + // no match we can add now + if (tasklist == null) { + tasklist = new TaskList(); + tasklist.setContentByLocalJSON(sqlNote.getContent()); + GTaskClient.getInstance().createTaskList(tasklist); + mGTaskListHashMap.put(tasklist.getGid(), tasklist); + } + n = (Node) tasklist; + } + + // update local note + sqlNote.setGtaskId(n.getGid()); + sqlNote.commit(false); + sqlNote.resetLocalModified(); + sqlNote.commit(true); + + // gid-id mapping + mGidToNid.put(n.getGid(), sqlNote.getId()); + mNidToGid.put(sqlNote.getId(), n.getGid()); + } + + private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException { + if (mCancelled) { + return; + } + + SqlNote sqlNote = new SqlNote(mContext, c); + + // update remotely + node.setContentByLocalJSON(sqlNote.getContent()); + GTaskClient.getInstance().addUpdateNode(node); + + // update meta + updateRemoteMeta(node.getGid(), sqlNote); + + // move task if necessary + if (sqlNote.isNoteType()) { + Task task = (Task) node; + TaskList preParentList = task.getParent(); + + String curParentGid = mNidToGid.get(sqlNote.getParentId()); + if (curParentGid == null) { + Log.e(TAG, "cannot find task's parent tasklist"); + throw new ActionFailureException("cannot update remote task"); + } + TaskList curParentList = mGTaskListHashMap.get(curParentGid); + + if (preParentList != curParentList) { + preParentList.removeChildTask(task); + curParentList.addChildTask(task); + GTaskClient.getInstance().moveTask(task, preParentList, curParentList); + } + } + + // clear local modified flag + sqlNote.resetLocalModified(); + sqlNote.commit(true); + } + + private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException { + if (sqlNote != null && sqlNote.isNoteType()) { + MetaData metaData = mMetaHashMap.get(gid); + if (metaData != null) { + metaData.setMeta(gid, sqlNote.getContent()); + GTaskClient.getInstance().addUpdateNode(metaData); + } else { + metaData = new MetaData(); + metaData.setMeta(gid, sqlNote.getContent()); + mMetaList.addChildTask(metaData); + mMetaHashMap.put(gid, metaData); + GTaskClient.getInstance().createTask(metaData); + } + } + } + + private void refreshLocalSyncId() throws NetworkFailureException { + if (mCancelled) { + return; + } + + // get the latest gtask list + mGTaskHashMap.clear(); + mGTaskListHashMap.clear(); + mMetaHashMap.clear(); + initGTaskList(); + + Cursor c = null; + try { + c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, + "(type<>? AND parent_id<>?)", new String[] { + String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER) + }, NoteColumns.TYPE + " DESC"); + if (c != null) { + while (c.moveToNext()) { + String gid = c.getString(SqlNote.GTASK_ID_COLUMN); + Node node = mGTaskHashMap.get(gid); + if (node != null) { + mGTaskHashMap.remove(gid); + ContentValues values = new ContentValues(); + values.put(NoteColumns.SYNC_ID, node.getLastModified()); + mContentResolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, + c.getLong(SqlNote.ID_COLUMN)), values, null, null); + } else { + Log.e(TAG, "something is missed"); + throw new ActionFailureException( + "some local items don't have gid after sync"); + } + } + } else { + Log.w(TAG, "failed to query local note to refresh sync id"); + } + } finally { + if (c != null) { + c.close(); + c = null; + } + } + } + + public String getSyncAccount() { + return GTaskClient.getInstance().getSyncAccount().name; + } + + public void cancelSync() { + mCancelled = true; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskSyncService.java b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskSyncService.java new file mode 100644 index 0000000..cca36f7 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/gtask/remote/GTaskSyncService.java @@ -0,0 +1,128 @@ +/* + * 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.remote; + +import android.app.Activity; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; + +public class GTaskSyncService extends Service { + public final static String ACTION_STRING_NAME = "sync_action_type"; + + public final static int ACTION_START_SYNC = 0; + + public final static int ACTION_CANCEL_SYNC = 1; + + public final static int ACTION_INVALID = 2; + + public final static String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.remote.gtask_sync_service"; + + public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "isSyncing"; + + public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg"; + + private static GTaskASyncTask mSyncTask = null; + + private static String mSyncProgress = ""; + + private void startSync() { + if (mSyncTask == null) { + mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() { + public void onComplete() { + mSyncTask = null; + sendBroadcast(""); + stopSelf(); + } + }); + sendBroadcast(""); + mSyncTask.execute(); + } + } + + private void cancelSync() { + if (mSyncTask != null) { + mSyncTask.cancelSync(); + } + } + + @Override + public void onCreate() { + mSyncTask = null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Bundle bundle = intent.getExtras(); + if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) { + switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) { + case ACTION_START_SYNC: + startSync(); + break; + case ACTION_CANCEL_SYNC: + cancelSync(); + break; + default: + break; + } + return START_STICKY; + } + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onLowMemory() { + if (mSyncTask != null) { + mSyncTask.cancelSync(); + } + } + + public IBinder onBind(Intent intent) { + return null; + } + + public void sendBroadcast(String msg) { + mSyncProgress = msg; + Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME); + intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null); + intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg); + sendBroadcast(intent); + } + + public static void startSync(Activity activity) { + GTaskManager.getInstance().setActivityContext(activity); + Intent intent = new Intent(activity, GTaskSyncService.class); + intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC); + activity.startService(intent); + } + + public static void cancelSync(Context context) { + Intent intent = new Intent(context, GTaskSyncService.class); + intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC); + context.startService(intent); + } + + public static boolean isSyncing() { + return mSyncTask != null; + } + + public static String getProgressString() { + return mSyncProgress; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/model/Note.java b/src/Notesmaster/app/src/test/java/net/micode/notes/model/Note.java new file mode 100644 index 0000000..6706cf6 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/model/Note.java @@ -0,0 +1,253 @@ +/* + * 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; +import android.content.ContentValues; +import android.content.Context; +import android.content.OperationApplicationException; +import android.net.Uri; +import android.os.RemoteException; +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.NoteColumns; +import net.micode.notes.data.Notes.TextNote; + +import java.util.ArrayList; + + +public class Note { + private ContentValues mNoteDiffValues; + private NoteData mNoteData; + 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 + 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) { + 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) { + mNoteData.setTextDataId(id); + } + + public long getTextDataId() { + return mNoteData.mTextDataId; + } + + public void setCallDataId(long 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; + + private ContentValues mTextDataValues; + + private long mCallDataId; + + private ContentValues mCallDataValues; + + private static final String TAG = "NoteData"; + + public NoteData() { + mTextDataValues = new ContentValues(); + mCallDataValues = new ContentValues(); + mTextDataId = 0; + mCallDataId = 0; + } + + boolean isLocalModified() { + return mTextDataValues.size() > 0 || mCallDataValues.size() > 0; + } + + void setTextDataId(long id) { + if(id <= 0) { + throw new IllegalArgumentException("Text data id should larger than 0"); + } + mTextDataId = id; + } + + void setCallDataId(long 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) { + /** + * 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) { + mTextDataValues.put(DataColumns.NOTE_ID, noteId); + if (mTextDataId == 0) { + 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) { + 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 { + 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/src/Notesmaster/app/src/test/java/net/micode/notes/model/WorkingNote.java b/src/Notesmaster/app/src/test/java/net/micode/notes/model/WorkingNote.java new file mode 100644 index 0000000..be081e4 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/model/WorkingNote.java @@ -0,0 +1,368 @@ +/* + * 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; + + +public class 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[] { + 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 + }; + + 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) { + mContext = context; + mAlertDate = 0; + mModifiedDate = System.currentTimeMillis(); + mFolderId = folderId; + mNote = new Note(); + mNoteId = 0; + mIsDeleted = false; + mMode = 0; + mWidgetType = Notes.TYPE_WIDGET_INVALIDE; + } + + // 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() { + 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() { + 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() { + return (mAlertDate > 0 ? true : false); + } + + public String getContent() { + return mContent; + } + + public long getAlertDate() { + return mAlertDate; + } + + public long getModifiedDate() { + return mModifiedDate; + } + + public int getBgColorResId() { + return NoteBgResources.getNoteBgResource(mBgColorId); + } + + public int getBgColorId() { + return mBgColorId; + } + + public int getTitleBgResId() { + return NoteBgResources.getNoteTitleBgResource(mBgColorId); + } + + public int getCheckListMode() { + return mMode; + } + + public long getNoteId() { + return mNoteId; + } + + public long getFolderId() { + return mFolderId; + } + + public int getWidgetId() { + 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/src/Notesmaster/app/src/test/java/net/micode/notes/tool/BackupUtils.java b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/BackupUtils.java new file mode 100644 index 0000000..39f6ec4 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/BackupUtils.java @@ -0,0 +1,344 @@ +/* + * 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.tool; + +import android.content.Context; +import android.database.Cursor; +import android.os.Environment; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.util.Log; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.DataConstants; +import net.micode.notes.data.Notes.NoteColumns; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; + + +public class BackupUtils { + private static final String TAG = "BackupUtils"; + // Singleton stuff + private static BackupUtils sInstance; + + public static synchronized BackupUtils getInstance(Context context) { + if (sInstance == null) { + sInstance = new BackupUtils(context); + } + return sInstance; + } + + /** + * Following states are signs to represents backup or restore + * status + */ + // Currently, the sdcard is not mounted + public static final int STATE_SD_CARD_UNMOUONTED = 0; + // The backup file not exist + public static final int STATE_BACKUP_FILE_NOT_EXIST = 1; + // The data is not well formated, may be changed by other programs + public static final int STATE_DATA_DESTROIED = 2; + // Some run-time exception which causes restore or backup fails + public static final int STATE_SYSTEM_ERROR = 3; + // Backup or restore success + public static final int STATE_SUCCESS = 4; + + private TextExport mTextExport; + + private BackupUtils(Context context) { + mTextExport = new TextExport(context); + } + + private static boolean externalStorageAvailable() { + return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); + } + + public int exportToText() { + return mTextExport.exportToText(); + } + + public String getExportedTextFileName() { + return mTextExport.mFileName; + } + + public String getExportedTextFileDir() { + return mTextExport.mFileDirectory; + } + + private static class TextExport { + private static final String[] NOTE_PROJECTION = { + NoteColumns.ID, + NoteColumns.MODIFIED_DATE, + NoteColumns.SNIPPET, + NoteColumns.TYPE + }; + + private static final int NOTE_COLUMN_ID = 0; + + private static final int NOTE_COLUMN_MODIFIED_DATE = 1; + + private static final int NOTE_COLUMN_SNIPPET = 2; + + private static final String[] DATA_PROJECTION = { + DataColumns.CONTENT, + DataColumns.MIME_TYPE, + DataColumns.DATA1, + DataColumns.DATA2, + DataColumns.DATA3, + DataColumns.DATA4, + }; + + private static final int DATA_COLUMN_CONTENT = 0; + + private static final int DATA_COLUMN_MIME_TYPE = 1; + + private static final int DATA_COLUMN_CALL_DATE = 2; + + private static final int DATA_COLUMN_PHONE_NUMBER = 4; + + private final String [] TEXT_FORMAT; + private static final int FORMAT_FOLDER_NAME = 0; + private static final int FORMAT_NOTE_DATE = 1; + private static final int FORMAT_NOTE_CONTENT = 2; + + private Context mContext; + private String mFileName; + private String mFileDirectory; + + public TextExport(Context context) { + TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note); + mContext = context; + mFileName = ""; + mFileDirectory = ""; + } + + private String getFormat(int id) { + return TEXT_FORMAT[id]; + } + + /** + * Export the folder identified by folder id to text + */ + private void exportFolderToText(String folderId, PrintStream ps) { + // Query notes belong to this folder + Cursor notesCursor = mContext.getContentResolver().query(Notes.CONTENT_NOTE_URI, + NOTE_PROJECTION, NoteColumns.PARENT_ID + "=?", new String[] { + folderId + }, null); + + if (notesCursor != null) { + if (notesCursor.moveToFirst()) { + do { + // Print note's last modified date + ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format( + mContext.getString(R.string.format_datetime_mdhm), + notesCursor.getLong(NOTE_COLUMN_MODIFIED_DATE)))); + // Query data belong to this note + String noteId = notesCursor.getString(NOTE_COLUMN_ID); + exportNoteToText(noteId, ps); + } while (notesCursor.moveToNext()); + } + notesCursor.close(); + } + } + + /** + * Export note identified by id to a print stream + */ + private void exportNoteToText(String noteId, PrintStream ps) { + Cursor dataCursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, + DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[] { + noteId + }, null); + + if (dataCursor != null) { + if (dataCursor.moveToFirst()) { + do { + String mimeType = dataCursor.getString(DATA_COLUMN_MIME_TYPE); + if (DataConstants.CALL_NOTE.equals(mimeType)) { + // Print phone number + String phoneNumber = dataCursor.getString(DATA_COLUMN_PHONE_NUMBER); + long callDate = dataCursor.getLong(DATA_COLUMN_CALL_DATE); + String location = dataCursor.getString(DATA_COLUMN_CONTENT); + + if (!TextUtils.isEmpty(phoneNumber)) { + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), + phoneNumber)); + } + // Print call date + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), DateFormat + .format(mContext.getString(R.string.format_datetime_mdhm), + callDate))); + // Print call attachment location + if (!TextUtils.isEmpty(location)) { + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), + location)); + } + } else if (DataConstants.NOTE.equals(mimeType)) { + String content = dataCursor.getString(DATA_COLUMN_CONTENT); + if (!TextUtils.isEmpty(content)) { + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), + content)); + } + } + } while (dataCursor.moveToNext()); + } + dataCursor.close(); + } + // print a line separator between note + try { + ps.write(new byte[] { + Character.LINE_SEPARATOR, Character.LETTER_NUMBER + }); + } catch (IOException e) { + Log.e(TAG, e.toString()); + } + } + + /** + * Note will be exported as text which is user readable + */ + public int exportToText() { + if (!externalStorageAvailable()) { + Log.d(TAG, "Media was not mounted"); + return STATE_SD_CARD_UNMOUONTED; + } + + PrintStream ps = getExportToTextPrintStream(); + if (ps == null) { + Log.e(TAG, "get print stream error"); + return STATE_SYSTEM_ERROR; + } + // First export folder and its notes + Cursor folderCursor = mContext.getContentResolver().query( + Notes.CONTENT_NOTE_URI, + NOTE_PROJECTION, + "(" + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + " AND " + + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + ") OR " + + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER, null, null); + + if (folderCursor != null) { + if (folderCursor.moveToFirst()) { + do { + // Print folder's name + String folderName = ""; + if(folderCursor.getLong(NOTE_COLUMN_ID) == Notes.ID_CALL_RECORD_FOLDER) { + folderName = mContext.getString(R.string.call_record_folder_name); + } else { + folderName = folderCursor.getString(NOTE_COLUMN_SNIPPET); + } + if (!TextUtils.isEmpty(folderName)) { + ps.println(String.format(getFormat(FORMAT_FOLDER_NAME), folderName)); + } + String folderId = folderCursor.getString(NOTE_COLUMN_ID); + exportFolderToText(folderId, ps); + } while (folderCursor.moveToNext()); + } + folderCursor.close(); + } + + // Export notes in root's folder + Cursor noteCursor = mContext.getContentResolver().query( + Notes.CONTENT_NOTE_URI, + NOTE_PROJECTION, + NoteColumns.TYPE + "=" + +Notes.TYPE_NOTE + " AND " + NoteColumns.PARENT_ID + + "=0", null, null); + + if (noteCursor != null) { + if (noteCursor.moveToFirst()) { + do { + ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format( + mContext.getString(R.string.format_datetime_mdhm), + noteCursor.getLong(NOTE_COLUMN_MODIFIED_DATE)))); + // Query data belong to this note + String noteId = noteCursor.getString(NOTE_COLUMN_ID); + exportNoteToText(noteId, ps); + } while (noteCursor.moveToNext()); + } + noteCursor.close(); + } + ps.close(); + + return STATE_SUCCESS; + } + + /** + * Get a print stream pointed to the file {@generateExportedTextFile} + */ + private PrintStream getExportToTextPrintStream() { + File file = generateFileMountedOnSDcard(mContext, R.string.file_path, + R.string.file_name_txt_format); + if (file == null) { + Log.e(TAG, "create file to exported failed"); + return null; + } + mFileName = file.getName(); + mFileDirectory = mContext.getString(R.string.file_path); + PrintStream ps = null; + try { + FileOutputStream fos = new FileOutputStream(file); + ps = new PrintStream(fos); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } catch (NullPointerException e) { + e.printStackTrace(); + return null; + } + return ps; + } + } + + /** + * Generate the text file to store imported data + */ + private static File generateFileMountedOnSDcard(Context context, int filePathResId, int fileNameFormatResId) { + StringBuilder sb = new StringBuilder(); + sb.append(Environment.getExternalStorageDirectory()); + sb.append(context.getString(filePathResId)); + File filedir = new File(sb.toString()); + sb.append(context.getString( + fileNameFormatResId, + DateFormat.format(context.getString(R.string.format_date_ymd), + System.currentTimeMillis()))); + File file = new File(sb.toString()); + + try { + if (!filedir.exists()) { + filedir.mkdir(); + } + if (!file.exists()) { + file.createNewFile(); + } + return file; + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } +} + + diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/tool/DataUtils.java b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/DataUtils.java new file mode 100644 index 0000000..2a14982 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/DataUtils.java @@ -0,0 +1,295 @@ +/* + * 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.tool; + +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.OperationApplicationException; +import android.database.Cursor; +import android.os.RemoteException; +import android.util.Log; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.CallNote; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute; + +import java.util.ArrayList; +import java.util.HashSet; + + +public class DataUtils { + public static final String TAG = "DataUtils"; + public static boolean batchDeleteNotes(ContentResolver resolver, HashSet ids) { + if (ids == null) { + Log.d(TAG, "the ids is null"); + return true; + } + if (ids.size() == 0) { + Log.d(TAG, "no id is in the hashset"); + return true; + } + + ArrayList operationList = new ArrayList(); + for (long id : ids) { + if(id == Notes.ID_ROOT_FOLDER) { + Log.e(TAG, "Don't delete system folder root"); + continue; + } + ContentProviderOperation.Builder builder = ContentProviderOperation + .newDelete(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id)); + operationList.add(builder.build()); + } + try { + ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList); + if (results == null || results.length == 0 || results[0] == null) { + Log.d(TAG, "delete notes failed, ids:" + ids.toString()); + return false; + } + return true; + } catch (RemoteException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } catch (OperationApplicationException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } + return false; + } + + public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.PARENT_ID, desFolderId); + values.put(NoteColumns.ORIGIN_PARENT_ID, srcFolderId); + values.put(NoteColumns.LOCAL_MODIFIED, 1); + resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null); + } + + public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids, + long folderId) { + if (ids == null) { + Log.d(TAG, "the ids is null"); + return true; + } + + ArrayList operationList = new ArrayList(); + for (long id : ids) { + ContentProviderOperation.Builder builder = ContentProviderOperation + .newUpdate(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id)); + builder.withValue(NoteColumns.PARENT_ID, folderId); + builder.withValue(NoteColumns.LOCAL_MODIFIED, 1); + operationList.add(builder.build()); + } + + try { + ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList); + if (results == null || results.length == 0 || results[0] == null) { + Log.d(TAG, "delete notes failed, ids:" + ids.toString()); + return false; + } + return true; + } catch (RemoteException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } catch (OperationApplicationException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + } + return false; + } + + /** + * Get the all folder count except system folders {@link Notes#TYPE_SYSTEM}} + */ + public static int getUserFolderCount(ContentResolver resolver) { + Cursor cursor =resolver.query(Notes.CONTENT_NOTE_URI, + new String[] { "COUNT(*)" }, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>?", + new String[] { String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER)}, + null); + + int count = 0; + if(cursor != null) { + if(cursor.moveToFirst()) { + try { + count = cursor.getInt(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "get folder count failed:" + e.toString()); + } finally { + cursor.close(); + } + } + } + return count; + } + + public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) { + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), + null, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER, + new String [] {String.valueOf(type)}, + null); + + boolean exist = false; + if (cursor != null) { + if (cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) { + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), + null, null, null, null); + + boolean exist = false; + if (cursor != null) { + if (cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static boolean existInDataDatabase(ContentResolver resolver, long dataId) { + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), + null, null, null, null); + + boolean exist = false; + if (cursor != null) { + if (cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static boolean checkVisibleFolderName(ContentResolver resolver, String name) { + Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, null, + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + + " AND " + NoteColumns.SNIPPET + "=?", + new String[] { name }, null); + boolean exist = false; + if(cursor != null) { + if(cursor.getCount() > 0) { + exist = true; + } + cursor.close(); + } + return exist; + } + + public static HashSet getFolderNoteWidget(ContentResolver resolver, long folderId) { + Cursor c = resolver.query(Notes.CONTENT_NOTE_URI, + new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE }, + NoteColumns.PARENT_ID + "=?", + new String[] { String.valueOf(folderId) }, + null); + + HashSet set = null; + if (c != null) { + if (c.moveToFirst()) { + set = new HashSet(); + do { + try { + AppWidgetAttribute widget = new AppWidgetAttribute(); + widget.widgetId = c.getInt(0); + widget.widgetType = c.getInt(1); + set.add(widget); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, e.toString()); + } + } while (c.moveToNext()); + } + c.close(); + } + return set; + } + + public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) { + Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, + new String [] { CallNote.PHONE_NUMBER }, + CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?", + new String [] { String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE }, + null); + + if (cursor != null && cursor.moveToFirst()) { + try { + return cursor.getString(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "Get call number fails " + e.toString()); + } finally { + cursor.close(); + } + } + return ""; + } + + public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) { + Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, + new String [] { CallNote.NOTE_ID }, + CallNote.CALL_DATE + "=? AND " + CallNote.MIME_TYPE + "=? AND PHONE_NUMBERS_EQUAL(" + + CallNote.PHONE_NUMBER + ",?)", + new String [] { String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber }, + null); + + if (cursor != null) { + if (cursor.moveToFirst()) { + try { + return cursor.getLong(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "Get call note id fails " + e.toString()); + } + } + cursor.close(); + } + return 0; + } + + public static String getSnippetById(ContentResolver resolver, long noteId) { + Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, + new String [] { NoteColumns.SNIPPET }, + NoteColumns.ID + "=?", + new String [] { String.valueOf(noteId)}, + null); + + if (cursor != null) { + String snippet = ""; + if (cursor.moveToFirst()) { + snippet = cursor.getString(0); + } + cursor.close(); + return snippet; + } + throw new IllegalArgumentException("Note is not found with id: " + noteId); + } + + public static String getFormattedSnippet(String snippet) { + if (snippet != null) { + snippet = snippet.trim(); + int index = snippet.indexOf('\n'); + if (index != -1) { + snippet = snippet.substring(0, index); + } + } + return snippet; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/tool/GTaskStringUtils.java b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/GTaskStringUtils.java new file mode 100644 index 0000000..666b729 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/GTaskStringUtils.java @@ -0,0 +1,113 @@ +/* + * 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.tool; + +public class GTaskStringUtils { + + public final static String GTASK_JSON_ACTION_ID = "action_id"; + + public final static String GTASK_JSON_ACTION_LIST = "action_list"; + + public final static String GTASK_JSON_ACTION_TYPE = "action_type"; + + public final static String GTASK_JSON_ACTION_TYPE_CREATE = "create"; + + public final static String GTASK_JSON_ACTION_TYPE_GETALL = "get_all"; + + public final static String GTASK_JSON_ACTION_TYPE_MOVE = "move"; + + public final static String GTASK_JSON_ACTION_TYPE_UPDATE = "update"; + + public final static String GTASK_JSON_CREATOR_ID = "creator_id"; + + public final static String GTASK_JSON_CHILD_ENTITY = "child_entity"; + + public final static String GTASK_JSON_CLIENT_VERSION = "client_version"; + + public final static String GTASK_JSON_COMPLETED = "completed"; + + public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id"; + + public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id"; + + public final static String GTASK_JSON_DELETED = "deleted"; + + public final static String GTASK_JSON_DEST_LIST = "dest_list"; + + public final static String GTASK_JSON_DEST_PARENT = "dest_parent"; + + public final static String GTASK_JSON_DEST_PARENT_TYPE = "dest_parent_type"; + + public final static String GTASK_JSON_ENTITY_DELTA = "entity_delta"; + + public final static String GTASK_JSON_ENTITY_TYPE = "entity_type"; + + public final static String GTASK_JSON_GET_DELETED = "get_deleted"; + + public final static String GTASK_JSON_ID = "id"; + + public final static String GTASK_JSON_INDEX = "index"; + + public final static String GTASK_JSON_LAST_MODIFIED = "last_modified"; + + public final static String GTASK_JSON_LATEST_SYNC_POINT = "latest_sync_point"; + + public final static String GTASK_JSON_LIST_ID = "list_id"; + + public final static String GTASK_JSON_LISTS = "lists"; + + public final static String GTASK_JSON_NAME = "name"; + + public final static String GTASK_JSON_NEW_ID = "new_id"; + + public final static String GTASK_JSON_NOTES = "notes"; + + public final static String GTASK_JSON_PARENT_ID = "parent_id"; + + public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id"; + + public final static String GTASK_JSON_RESULTS = "results"; + + public final static String GTASK_JSON_SOURCE_LIST = "source_list"; + + public final static String GTASK_JSON_TASKS = "tasks"; + + public final static String GTASK_JSON_TYPE = "type"; + + public final static String GTASK_JSON_TYPE_GROUP = "GROUP"; + + public final static String GTASK_JSON_TYPE_TASK = "TASK"; + + public final static String GTASK_JSON_USER = "user"; + + public final static String MIUI_FOLDER_PREFFIX = "[MIUI_Notes]"; + + public final static String FOLDER_DEFAULT = "Default"; + + public final static String FOLDER_CALL_NOTE = "Call_Note"; + + public final static String FOLDER_META = "METADATA"; + + public final static String META_HEAD_GTASK_ID = "meta_gid"; + + public final static String META_HEAD_NOTE = "meta_note"; + + public final static String META_HEAD_DATA = "meta_data"; + + public final static String META_NOTE_NAME = "[META INFO] DON'T UPDATE AND DELETE"; + +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/tool/ResourceParser.java b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/ResourceParser.java new file mode 100644 index 0000000..1ad3ad6 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/tool/ResourceParser.java @@ -0,0 +1,181 @@ +/* + * 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.tool; + +import android.content.Context; +import android.preference.PreferenceManager; + +import net.micode.notes.R; +import net.micode.notes.ui.NotesPreferenceActivity; + +public class ResourceParser { + + public static final int YELLOW = 0; + public static final int BLUE = 1; + public static final int WHITE = 2; + public static final int GREEN = 3; + public static final int RED = 4; + + public static final int BG_DEFAULT_COLOR = YELLOW; + + public static final int TEXT_SMALL = 0; + public static final int TEXT_MEDIUM = 1; + public static final int TEXT_LARGE = 2; + public static final int TEXT_SUPER = 3; + + public static final int BG_DEFAULT_FONT_SIZE = TEXT_MEDIUM; + + public static class NoteBgResources { + private final static int [] BG_EDIT_RESOURCES = new int [] { + R.drawable.edit_yellow, + R.drawable.edit_blue, + R.drawable.edit_white, + R.drawable.edit_green, + R.drawable.edit_red + }; + + private final static int [] BG_EDIT_TITLE_RESOURCES = new int [] { + R.drawable.edit_title_yellow, + R.drawable.edit_title_blue, + R.drawable.edit_title_white, + R.drawable.edit_title_green, + R.drawable.edit_title_red + }; + + public static int getNoteBgResource(int id) { + return BG_EDIT_RESOURCES[id]; + } + + public static int getNoteTitleBgResource(int id) { + return BG_EDIT_TITLE_RESOURCES[id]; + } + } + + public static int getDefaultBgId(Context context) { + if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean( + NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) { + return (int) (Math.random() * NoteBgResources.BG_EDIT_RESOURCES.length); + } else { + return BG_DEFAULT_COLOR; + } + } + + public static class NoteItemBgResources { + private final static int [] BG_FIRST_RESOURCES = new int [] { + R.drawable.list_yellow_up, + R.drawable.list_blue_up, + R.drawable.list_white_up, + R.drawable.list_green_up, + R.drawable.list_red_up + }; + + private final static int [] BG_NORMAL_RESOURCES = new int [] { + R.drawable.list_yellow_middle, + R.drawable.list_blue_middle, + R.drawable.list_white_middle, + R.drawable.list_green_middle, + R.drawable.list_red_middle + }; + + private final static int [] BG_LAST_RESOURCES = new int [] { + R.drawable.list_yellow_down, + R.drawable.list_blue_down, + R.drawable.list_white_down, + R.drawable.list_green_down, + R.drawable.list_red_down, + }; + + private final static int [] BG_SINGLE_RESOURCES = new int [] { + R.drawable.list_yellow_single, + R.drawable.list_blue_single, + R.drawable.list_white_single, + R.drawable.list_green_single, + R.drawable.list_red_single + }; + + public static int getNoteBgFirstRes(int id) { + return BG_FIRST_RESOURCES[id]; + } + + public static int getNoteBgLastRes(int id) { + return BG_LAST_RESOURCES[id]; + } + + public static int getNoteBgSingleRes(int id) { + return BG_SINGLE_RESOURCES[id]; + } + + public static int getNoteBgNormalRes(int id) { + return BG_NORMAL_RESOURCES[id]; + } + + public static int getFolderBgRes() { + return R.drawable.list_folder; + } + } + + public static class WidgetBgResources { + private final static int [] BG_2X_RESOURCES = new int [] { + R.drawable.widget_2x_yellow, + R.drawable.widget_2x_blue, + R.drawable.widget_2x_white, + R.drawable.widget_2x_green, + R.drawable.widget_2x_red, + }; + + public static int getWidget2xBgResource(int id) { + return BG_2X_RESOURCES[id]; + } + + private final static int [] BG_4X_RESOURCES = new int [] { + R.drawable.widget_4x_yellow, + R.drawable.widget_4x_blue, + R.drawable.widget_4x_white, + R.drawable.widget_4x_green, + R.drawable.widget_4x_red + }; + + public static int getWidget4xBgResource(int id) { + return BG_4X_RESOURCES[id]; + } + } + + public static class TextAppearanceResources { + private final static int [] TEXTAPPEARANCE_RESOURCES = new int [] { + R.style.TextAppearanceNormal, + R.style.TextAppearanceMedium, + R.style.TextAppearanceLarge, + R.style.TextAppearanceSuper + }; + + public static int getTexAppearanceResource(int id) { + /** + * HACKME: Fix bug of store the resource id in shared preference. + * The id may larger than the length of resources, in this case, + * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE} + */ + if (id >= TEXTAPPEARANCE_RESOURCES.length) { + return BG_DEFAULT_FONT_SIZE; + } + return TEXTAPPEARANCE_RESOURCES[id]; + } + + public static int getResourcesSize() { + return TEXTAPPEARANCE_RESOURCES.length; + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmAlertActivity.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmAlertActivity.java new file mode 100644 index 0000000..85723be --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmAlertActivity.java @@ -0,0 +1,158 @@ +/* + * 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.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.DialogInterface.OnDismissListener; +import android.content.Intent; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Bundle; +import android.os.PowerManager; +import android.provider.Settings; +import android.view.Window; +import android.view.WindowManager; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.DataUtils; + +import java.io.IOException; + + +public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { + private long mNoteId; + private String mSnippet; + private static final int SNIPPET_PREW_MAX_LEN = 60; + MediaPlayer mPlayer; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + + final Window win = getWindow(); + win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + + if (!isScreenOn()) { + win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON + | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); + } + + Intent intent = getIntent(); + + try { + mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); + mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); + mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, + SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) + : mSnippet; + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return; + } + + mPlayer = new MediaPlayer(); + if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { + showActionDialog(); + playAlarmSound(); + } else { + finish(); + } + } + + private boolean isScreenOn() { + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + return pm.isScreenOn(); + } + + private void playAlarmSound() { + Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); + + int silentModeStreams = Settings.System.getInt(getContentResolver(), + Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); + + if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { + mPlayer.setAudioStreamType(silentModeStreams); + } else { + mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); + } + try { + mPlayer.setDataSource(this, url); + mPlayer.prepare(); + mPlayer.setLooping(true); + mPlayer.start(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private void showActionDialog() { + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle(R.string.app_name); + dialog.setMessage(mSnippet); + dialog.setPositiveButton(R.string.notealert_ok, this); + if (isScreenOn()) { + dialog.setNegativeButton(R.string.notealert_enter, this); + } + dialog.show().setOnDismissListener(this); + } + + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_NEGATIVE: + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.putExtra(Intent.EXTRA_UID, mNoteId); + startActivity(intent); + break; + default: + break; + } + } + + public void onDismiss(DialogInterface dialog) { + stopAlarmSound(); + finish(); + } + + private void stopAlarmSound() { + if (mPlayer != null) { + mPlayer.stop(); + mPlayer.release(); + mPlayer = null; + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmInitReceiver.java new file mode 100644 index 0000000..f221202 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmInitReceiver.java @@ -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.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; + + +public class AlarmInitReceiver extends BroadcastReceiver { + + private static final String [] PROJECTION = new String [] { + NoteColumns.ID, + NoteColumns.ALERTED_DATE + }; + + private static final int COLUMN_ID = 0; + private static final int COLUMN_ALERTED_DATE = 1; + + @Override + public void onReceive(Context context, Intent intent) { + long currentDate = System.currentTimeMillis(); + Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, + PROJECTION, + NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, + new String[] { String.valueOf(currentDate) }, + null); + + if (c != null) { + if (c.moveToFirst()) { + do { + long alertDate = c.getLong(COLUMN_ALERTED_DATE); + Intent sender = new Intent(context, AlarmReceiver.class); + sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); + AlarmManager alermManager = (AlarmManager) context + .getSystemService(Context.ALARM_SERVICE); + alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); + } while (c.moveToNext()); + } + c.close(); + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmReceiver.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmReceiver.java new file mode 100644 index 0000000..54e503b --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/AlarmReceiver.java @@ -0,0 +1,30 @@ +/* + * 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.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class AlarmReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + intent.setClass(context, AlarmAlertActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePicker.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePicker.java new file mode 100644 index 0000000..496b0cd --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePicker.java @@ -0,0 +1,485 @@ +/* + * 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 java.text.DateFormatSymbols; +import java.util.Calendar; + +import net.micode.notes.R; + + +import android.content.Context; +import android.text.format.DateFormat; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.NumberPicker; + +public class DateTimePicker extends FrameLayout { + + private static final boolean DEFAULT_ENABLE_STATE = true; + + private static final int HOURS_IN_HALF_DAY = 12; + private static final int HOURS_IN_ALL_DAY = 24; + private static final int DAYS_IN_ALL_WEEK = 7; + private static final int DATE_SPINNER_MIN_VAL = 0; + private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1; + private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0; + private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23; + private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1; + private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12; + private static final int MINUT_SPINNER_MIN_VAL = 0; + private static final int MINUT_SPINNER_MAX_VAL = 59; + private static final int AMPM_SPINNER_MIN_VAL = 0; + private static final int AMPM_SPINNER_MAX_VAL = 1; + + private final NumberPicker mDateSpinner; + private final NumberPicker mHourSpinner; + private final NumberPicker mMinuteSpinner; + private final NumberPicker mAmPmSpinner; + private Calendar mDate; + + private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; + + private boolean mIsAm; + + private boolean mIs24HourView; + + private boolean mIsEnabled = DEFAULT_ENABLE_STATE; + + private boolean mInitialising; + + private OnDateTimeChangedListener mOnDateTimeChangedListener; + + private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); + updateDateControl(); + onDateTimeChanged(); + } + }; + + private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + boolean isDateChanged = false; + Calendar cal = Calendar.getInstance(); + if (!mIs24HourView) { + if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, 1); + isDateChanged = true; + } else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, -1); + isDateChanged = true; + } + if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || + oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + } else { + if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, 1); + isDateChanged = true; + } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, -1); + isDateChanged = true; + } + } + int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); + mDate.set(Calendar.HOUR_OF_DAY, newHour); + onDateTimeChanged(); + if (isDateChanged) { + setCurrentYear(cal.get(Calendar.YEAR)); + setCurrentMonth(cal.get(Calendar.MONTH)); + setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); + } + } + }; + + private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + int minValue = mMinuteSpinner.getMinValue(); + int maxValue = mMinuteSpinner.getMaxValue(); + int offset = 0; + if (oldVal == maxValue && newVal == minValue) { + offset += 1; + } else if (oldVal == minValue && newVal == maxValue) { + offset -= 1; + } + if (offset != 0) { + mDate.add(Calendar.HOUR_OF_DAY, offset); + mHourSpinner.setValue(getCurrentHour()); + updateDateControl(); + int newHour = getCurrentHourOfDay(); + if (newHour >= HOURS_IN_HALF_DAY) { + mIsAm = false; + updateAmPmControl(); + } else { + mIsAm = true; + updateAmPmControl(); + } + } + mDate.set(Calendar.MINUTE, newVal); + onDateTimeChanged(); + } + }; + + private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + mIsAm = !mIsAm; + if (mIsAm) { + mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY); + } else { + mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY); + } + updateAmPmControl(); + onDateTimeChanged(); + } + }; + + public interface OnDateTimeChangedListener { + void onDateTimeChanged(DateTimePicker view, int year, int month, + int dayOfMonth, int hourOfDay, int minute); + } + + public DateTimePicker(Context context) { + this(context, System.currentTimeMillis()); + } + + public DateTimePicker(Context context, long date) { + this(context, date, DateFormat.is24HourFormat(context)); + } + + public DateTimePicker(Context context, long date, boolean is24HourView) { + super(context); + mDate = Calendar.getInstance(); + mInitialising = true; + mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; + inflate(context, R.layout.datetime_picker, this); + + mDateSpinner = (NumberPicker) findViewById(R.id.date); + mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); + mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); + mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); + + mHourSpinner = (NumberPicker) findViewById(R.id.hour); + mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); + mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); + mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); + mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); + mMinuteSpinner.setOnLongPressUpdateInterval(100); + mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); + + String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); + mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); + mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL); + mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL); + mAmPmSpinner.setDisplayedValues(stringsForAmPm); + mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); + + // update controls to initial state + updateDateControl(); + updateHourControl(); + updateAmPmControl(); + + set24HourView(is24HourView); + + // set to current time + setCurrentDate(date); + + setEnabled(isEnabled()); + + // set the content descriptions + mInitialising = false; + } + + @Override + public void setEnabled(boolean enabled) { + if (mIsEnabled == enabled) { + return; + } + super.setEnabled(enabled); + mDateSpinner.setEnabled(enabled); + mMinuteSpinner.setEnabled(enabled); + mHourSpinner.setEnabled(enabled); + mAmPmSpinner.setEnabled(enabled); + mIsEnabled = enabled; + } + + @Override + public boolean isEnabled() { + return mIsEnabled; + } + + /** + * Get the current date in millis + * + * @return the current date in millis + */ + public long getCurrentDateInTimeMillis() { + return mDate.getTimeInMillis(); + } + + /** + * Set the current date + * + * @param date The current date in millis + */ + public void setCurrentDate(long date) { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(date); + setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), + cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); + } + + /** + * Set the current date + * + * @param year The current year + * @param month The current month + * @param dayOfMonth The current dayOfMonth + * @param hourOfDay The current hourOfDay + * @param minute The current minute + */ + public void setCurrentDate(int year, int month, + int dayOfMonth, int hourOfDay, int minute) { + setCurrentYear(year); + setCurrentMonth(month); + setCurrentDay(dayOfMonth); + setCurrentHour(hourOfDay); + setCurrentMinute(minute); + } + + /** + * Get current year + * + * @return The current year + */ + public int getCurrentYear() { + return mDate.get(Calendar.YEAR); + } + + /** + * Set current year + * + * @param year The current year + */ + public void setCurrentYear(int year) { + if (!mInitialising && year == getCurrentYear()) { + return; + } + mDate.set(Calendar.YEAR, year); + updateDateControl(); + onDateTimeChanged(); + } + + /** + * Get current month in the year + * + * @return The current month in the year + */ + public int getCurrentMonth() { + return mDate.get(Calendar.MONTH); + } + + /** + * Set current month in the year + * + * @param month The month in the year + */ + public void setCurrentMonth(int month) { + if (!mInitialising && month == getCurrentMonth()) { + return; + } + mDate.set(Calendar.MONTH, month); + updateDateControl(); + onDateTimeChanged(); + } + + /** + * Get current day of the month + * + * @return The day of the month + */ + public int getCurrentDay() { + return mDate.get(Calendar.DAY_OF_MONTH); + } + + /** + * Set current day of the month + * + * @param dayOfMonth The day of the month + */ + public void setCurrentDay(int dayOfMonth) { + if (!mInitialising && dayOfMonth == getCurrentDay()) { + return; + } + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + updateDateControl(); + onDateTimeChanged(); + } + + /** + * Get current hour in 24 hour mode, in the range (0~23) + * @return The current hour in 24 hour mode + */ + public int getCurrentHourOfDay() { + return mDate.get(Calendar.HOUR_OF_DAY); + } + + private int getCurrentHour() { + if (mIs24HourView){ + return getCurrentHourOfDay(); + } else { + int hour = getCurrentHourOfDay(); + if (hour > HOURS_IN_HALF_DAY) { + return hour - HOURS_IN_HALF_DAY; + } else { + return hour == 0 ? HOURS_IN_HALF_DAY : hour; + } + } + } + + /** + * Set current hour in 24 hour mode, in the range (0~23) + * + * @param hourOfDay + */ + public void setCurrentHour(int hourOfDay) { + if (!mInitialising && hourOfDay == getCurrentHourOfDay()) { + return; + } + mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + if (!mIs24HourView) { + if (hourOfDay >= HOURS_IN_HALF_DAY) { + mIsAm = false; + if (hourOfDay > HOURS_IN_HALF_DAY) { + hourOfDay -= HOURS_IN_HALF_DAY; + } + } else { + mIsAm = true; + if (hourOfDay == 0) { + hourOfDay = HOURS_IN_HALF_DAY; + } + } + updateAmPmControl(); + } + mHourSpinner.setValue(hourOfDay); + onDateTimeChanged(); + } + + /** + * Get currentMinute + * + * @return The Current Minute + */ + public int getCurrentMinute() { + return mDate.get(Calendar.MINUTE); + } + + /** + * Set current minute + */ + public void setCurrentMinute(int minute) { + if (!mInitialising && minute == getCurrentMinute()) { + return; + } + mMinuteSpinner.setValue(minute); + mDate.set(Calendar.MINUTE, minute); + onDateTimeChanged(); + } + + /** + * @return true if this is in 24 hour view else false. + */ + public boolean is24HourView () { + return mIs24HourView; + } + + /** + * Set whether in 24 hour or AM/PM mode. + * + * @param is24HourView True for 24 hour mode. False for AM/PM mode. + */ + public void set24HourView(boolean is24HourView) { + if (mIs24HourView == is24HourView) { + return; + } + mIs24HourView = is24HourView; + mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE); + int hour = getCurrentHourOfDay(); + updateHourControl(); + setCurrentHour(hour); + updateAmPmControl(); + } + + private void updateDateControl() { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(mDate.getTimeInMillis()); + cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); + mDateSpinner.setDisplayedValues(null); + for (int i = 0; i < DAYS_IN_ALL_WEEK; ++i) { + cal.add(Calendar.DAY_OF_YEAR, 1); + mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal); + } + mDateSpinner.setDisplayedValues(mDateDisplayValues); + mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); + mDateSpinner.invalidate(); + } + + private void updateAmPmControl() { + if (mIs24HourView) { + mAmPmSpinner.setVisibility(View.GONE); + } else { + int index = mIsAm ? Calendar.AM : Calendar.PM; + mAmPmSpinner.setValue(index); + mAmPmSpinner.setVisibility(View.VISIBLE); + } + } + + private void updateHourControl() { + if (mIs24HourView) { + mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW); + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); + } else { + mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); + mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); + } + } + + /** + * Set the callback that indicates the 'Set' button has been pressed. + * @param callback the callback, if null will do nothing + */ + public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { + mOnDateTimeChangedListener = callback; + } + + private void onDateTimeChanged() { + if (mOnDateTimeChangedListener != null) { + mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(), + getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePickerDialog.java new file mode 100644 index 0000000..2c47ba4 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DateTimePickerDialog.java @@ -0,0 +1,90 @@ +/* + * 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 java.util.Calendar; + +import net.micode.notes.R; +import net.micode.notes.ui.DateTimePicker; +import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.text.format.DateFormat; +import android.text.format.DateUtils; + +public class DateTimePickerDialog extends AlertDialog implements OnClickListener { + + private Calendar mDate = Calendar.getInstance(); + private boolean mIs24HourView; + private OnDateTimeSetListener mOnDateTimeSetListener; + private DateTimePicker mDateTimePicker; + + public interface OnDateTimeSetListener { + void OnDateTimeSet(AlertDialog dialog, long date); + } + + public DateTimePickerDialog(Context context, long date) { + super(context); + mDateTimePicker = new DateTimePicker(context); + setView(mDateTimePicker); + mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { + public void onDateTimeChanged(DateTimePicker view, int year, int month, + int dayOfMonth, int hourOfDay, int minute) { + mDate.set(Calendar.YEAR, year); + mDate.set(Calendar.MONTH, month); + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + mDate.set(Calendar.MINUTE, minute); + updateTitle(mDate.getTimeInMillis()); + } + }); + mDate.setTimeInMillis(date); + mDate.set(Calendar.SECOND, 0); + mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); + setButton(context.getString(R.string.datetime_dialog_ok), this); + setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); + set24HourView(DateFormat.is24HourFormat(this.getContext())); + updateTitle(mDate.getTimeInMillis()); + } + + public void set24HourView(boolean is24HourView) { + mIs24HourView = is24HourView; + } + + public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { + mOnDateTimeSetListener = callBack; + } + + private void updateTitle(long date) { + int flag = + DateUtils.FORMAT_SHOW_YEAR | + DateUtils.FORMAT_SHOW_DATE | + DateUtils.FORMAT_SHOW_TIME; + flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; + setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); + } + + public void onClick(DialogInterface arg0, int arg1) { + if (mOnDateTimeSetListener != null) { + mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); + } + } + +} \ No newline at end of file diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DropdownMenu.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DropdownMenu.java new file mode 100644 index 0000000..613dc74 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/DropdownMenu.java @@ -0,0 +1,61 @@ +/* + * 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; + + 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); + } + } + + public MenuItem findItem(int id) { + return mMenu.findItem(id); + } + + public void setTitle(CharSequence title) { + mButton.setText(title); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/FoldersListAdapter.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/FoldersListAdapter.java new file mode 100644 index 0000000..96b77da --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/FoldersListAdapter.java @@ -0,0 +1,80 @@ +/* + * 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 { + public static final String [] PROJECTION = { + NoteColumns.ID, + NoteColumns.SNIPPET + }; + + public static final int ID_COLUMN = 0; + 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) { + 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 { + 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); + } + } + +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditActivity.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditActivity.java new file mode 100644 index 0000000..96a9ff8 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditActivity.java @@ -0,0 +1,873 @@ +/* + * 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.app.Activity; +import android.app.AlarmManager; +import android.app.AlertDialog; +import android.app.PendingIntent; +import android.app.SearchManager; +import android.appwidget.AppWidgetManager; +import android.content.ContentUris; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Paint; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.format.DateUtils; +import android.text.style.BackgroundColorSpan; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.TextNote; +import net.micode.notes.model.WorkingNote; +import net.micode.notes.model.WorkingNote.NoteSettingChangedListener; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.ResourceParser; +import net.micode.notes.tool.ResourceParser.TextAppearanceResources; +import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener; +import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener; +import net.micode.notes.widget.NoteWidgetProvider_2x; +import net.micode.notes.widget.NoteWidgetProvider_4x; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class NoteEditActivity extends Activity implements OnClickListener, + NoteSettingChangedListener, OnTextViewChangeListener { + private class HeadViewHolder { + public TextView tvModified; + + public ImageView ivAlertIcon; + + public TextView tvAlertDate; + + public ImageView ibSetBgColor; + } + + private static final Map sBgSelectorBtnsMap = new HashMap(); + static { + sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); + sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED); + sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE); + sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN); + sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE); + } + + private static final Map sBgSelectorSelectionMap = new HashMap(); + static { + sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select); + sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select); + sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select); + sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select); + sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); + } + + private static final Map sFontSizeBtnsMap = new HashMap(); + static { + sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE); + sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL); + sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM); + sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); + } + + private static final Map sFontSelectorSelectionMap = new HashMap(); + static { + sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select); + sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); + } + + private static final String TAG = "NoteEditActivity"; + + private HeadViewHolder mNoteHeaderHolder; + + private View mHeadViewPanel; + + private View mNoteBgColorSelector; + + private View mFontSizeSelector; + + private EditText mNoteEditor; + + private View mNoteEditorPanel; + + private WorkingNote mWorkingNote; + + private SharedPreferences mSharedPrefs; + private int mFontSizeId; + + private static final String PREFERENCE_FONT_SIZE = "pref_font_size"; + + private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10; + + public static final String TAG_CHECKED = String.valueOf('\u221A'); + public static final String TAG_UNCHECKED = String.valueOf('\u25A1'); + + private LinearLayout mEditTextList; + + private String mUserQuery; + private Pattern mPattern; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.note_edit); + + if (savedInstanceState == null && !initActivityState(getIntent())) { + finish(); + return; + } + initResources(); + } + + /** + * Current activity may be killed when the memory is low. Once it is killed, for another time + * user load this activity, we should restore the former state + */ + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID)); + if (!initActivityState(intent)) { + finish(); + return; + } + Log.d(TAG, "Restoring from killed activity"); + } + } + + private boolean initActivityState(Intent intent) { + /** + * If the user specified the {@link Intent#ACTION_VIEW} but not provided with id, + * then jump to the NotesListActivity + */ + mWorkingNote = null; + if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) { + long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); + mUserQuery = ""; + + /** + * Starting from the searched result + */ + if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) { + noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); + mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); + } + + if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) { + Intent jump = new Intent(this, NotesListActivity.class); + startActivity(jump); + showToast(R.string.error_note_not_exist); + finish(); + return false; + } else { + mWorkingNote = WorkingNote.load(this, noteId); + if (mWorkingNote == null) { + Log.e(TAG, "load note failed with note id" + noteId); + finish(); + return false; + } + } + getWindow().setSoftInputMode( + WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { + // New note + long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); + int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + int widgetType = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, + Notes.TYPE_WIDGET_INVALIDE); + int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, + ResourceParser.getDefaultBgId(this)); + + // Parse call-record note + String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); + long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0); + if (callDate != 0 && phoneNumber != null) { + if (TextUtils.isEmpty(phoneNumber)) { + Log.w(TAG, "The call record number is null"); + } + long noteId = 0; + if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(), + phoneNumber, callDate)) > 0) { + mWorkingNote = WorkingNote.load(this, noteId); + if (mWorkingNote == null) { + Log.e(TAG, "load call note failed with note id" + noteId); + finish(); + return false; + } + } else { + mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, + widgetType, bgResId); + mWorkingNote.convertToCallNote(phoneNumber, callDate); + } + } else { + mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, + bgResId); + } + + getWindow().setSoftInputMode( + WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE + | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } else { + Log.e(TAG, "Intent not specified action, should not support"); + finish(); + return false; + } + mWorkingNote.setOnSettingStatusChangedListener(this); + return true; + } + + @Override + protected void onResume() { + super.onResume(); + initNoteScreen(); + } + + private void initNoteScreen() { + mNoteEditor.setTextAppearance(this, TextAppearanceResources + .getTexAppearanceResource(mFontSizeId)); + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + switchToListMode(mWorkingNote.getContent()); + } else { + mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); + mNoteEditor.setSelection(mNoteEditor.getText().length()); + } + for (Integer id : sBgSelectorSelectionMap.keySet()) { + findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE); + } + mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); + mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); + + mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this, + mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_SHOW_YEAR)); + + /** + * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker + * is not ready + */ + showAlertHeader(); + } + + private void showAlertHeader() { + if (mWorkingNote.hasClockAlert()) { + long time = System.currentTimeMillis(); + if (time > mWorkingNote.getAlertDate()) { + mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired); + } else { + mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString( + mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS)); + } + mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE); + mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE); + } else { + mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE); + mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); + }; + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + initActivityState(intent); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + /** + * For new note without note id, we should firstly save it to + * generate a id. If the editing note is not worth saving, there + * is no id which is equivalent to create new note + */ + if (!mWorkingNote.existInDatabase()) { + saveNote(); + } + outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState"); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (mNoteBgColorSelector.getVisibility() == View.VISIBLE + && !inRangeOfView(mNoteBgColorSelector, ev)) { + mNoteBgColorSelector.setVisibility(View.GONE); + return true; + } + + if (mFontSizeSelector.getVisibility() == View.VISIBLE + && !inRangeOfView(mFontSizeSelector, ev)) { + mFontSizeSelector.setVisibility(View.GONE); + return true; + } + return super.dispatchTouchEvent(ev); + } + + private boolean inRangeOfView(View view, MotionEvent ev) { + int []location = new int[2]; + view.getLocationOnScreen(location); + int x = location[0]; + int y = location[1]; + if (ev.getX() < x + || ev.getX() > (x + view.getWidth()) + || ev.getY() < y + || ev.getY() > (y + view.getHeight())) { + return false; + } + return true; + } + + private void initResources() { + mHeadViewPanel = findViewById(R.id.note_title); + mNoteHeaderHolder = new HeadViewHolder(); + mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date); + mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon); + mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date); + mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color); + mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this); + mNoteEditor = (EditText) findViewById(R.id.note_edit_view); + mNoteEditorPanel = findViewById(R.id.sv_note_edit); + mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector); + for (int id : sBgSelectorBtnsMap.keySet()) { + ImageView iv = (ImageView) findViewById(id); + iv.setOnClickListener(this); + } + + mFontSizeSelector = findViewById(R.id.font_size_selector); + for (int id : sFontSizeBtnsMap.keySet()) { + View view = findViewById(id); + view.setOnClickListener(this); + }; + mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE); + /** + * HACKME: Fix bug of store the resource id in shared preference. + * The id may larger than the length of resources, in this case, + * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE} + */ + if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { + mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; + } + mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); + } + + @Override + protected void onPause() { + super.onPause(); + if(saveNote()) { + Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); + } + clearSettingState(); + } + + private void updateWidget() { + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) { + intent.setClass(this, NoteWidgetProvider_2x.class); + } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) { + intent.setClass(this, NoteWidgetProvider_4x.class); + } else { + Log.e(TAG, "Unspported widget type"); + return; + } + + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { + mWorkingNote.getWidgetId() + }); + + sendBroadcast(intent); + setResult(RESULT_OK, intent); + } + + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.btn_set_bg_color) { + mNoteBgColorSelector.setVisibility(View.VISIBLE); + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + - View.VISIBLE); + } else if (sBgSelectorBtnsMap.containsKey(id)) { + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + View.GONE); + mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id)); + mNoteBgColorSelector.setVisibility(View.GONE); + } else if (sFontSizeBtnsMap.containsKey(id)) { + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE); + mFontSizeId = sFontSizeBtnsMap.get(id); + mSharedPrefs.edit().putInt(PREFERENCE_FONT_SIZE, mFontSizeId).commit(); + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + getWorkingText(); + switchToListMode(mWorkingNote.getContent()); + } else { + mNoteEditor.setTextAppearance(this, + TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); + } + mFontSizeSelector.setVisibility(View.GONE); + } + } + + @Override + public void onBackPressed() { + if(clearSettingState()) { + return; + } + + saveNote(); + super.onBackPressed(); + } + + private boolean clearSettingState() { + if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { + mNoteBgColorSelector.setVisibility(View.GONE); + return true; + } else if (mFontSizeSelector.getVisibility() == View.VISIBLE) { + mFontSizeSelector.setVisibility(View.GONE); + return true; + } + return false; + } + + public void onBackgroundColorChanged() { + findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( + View.VISIBLE); + mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); + mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (isFinishing()) { + return true; + } + clearSettingState(); + menu.clear(); + if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) { + getMenuInflater().inflate(R.menu.call_note_edit, menu); + } else { + getMenuInflater().inflate(R.menu.note_edit, menu); + } + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_normal_mode); + } else { + menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode); + } + if (mWorkingNote.hasClockAlert()) { + menu.findItem(R.id.menu_alert).setVisible(false); + } else { + menu.findItem(R.id.menu_delete_remind).setVisible(false); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_new_note: + createNewNote(); + break; + case R.id.menu_delete: + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.alert_title_delete)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_note)); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + deleteCurrentNote(); + finish(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + break; + case R.id.menu_font_size: + mFontSizeSelector.setVisibility(View.VISIBLE); + findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE); + break; + case R.id.menu_list_mode: + mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ? + TextNote.MODE_CHECK_LIST : 0); + break; + case R.id.menu_share: + getWorkingText(); + sendTo(this, mWorkingNote.getContent()); + break; + case R.id.menu_send_to_desktop: + sendToDesktop(); + break; + case R.id.menu_alert: + setReminder(); + break; + case R.id.menu_delete_remind: + mWorkingNote.setAlertDate(0, false); + break; + default: + break; + } + return true; + } + + private void setReminder() { + DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis()); + d.setOnDateTimeSetListener(new OnDateTimeSetListener() { + public void OnDateTimeSet(AlertDialog dialog, long date) { + mWorkingNote.setAlertDate(date , true); + } + }); + d.show(); + } + + /** + * Share note to apps that support {@link Intent#ACTION_SEND} action + * and {@text/plain} type + */ + private void sendTo(Context context, String info) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_TEXT, info); + intent.setType("text/plain"); + context.startActivity(intent); + } + + private void createNewNote() { + // Firstly, save current editing notes + saveNote(); + + // For safety, start a new NoteEditActivity + finish(); + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_INSERT_OR_EDIT); + intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId()); + startActivity(intent); + } + + private void deleteCurrentNote() { + if (mWorkingNote.existInDatabase()) { + HashSet ids = new HashSet(); + long id = mWorkingNote.getNoteId(); + if (id != Notes.ID_ROOT_FOLDER) { + ids.add(id); + } else { + Log.d(TAG, "Wrong note id, should not happen"); + } + if (!isSyncMode()) { + if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) { + Log.e(TAG, "Delete Note error"); + } + } else { + if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) { + Log.e(TAG, "Move notes to trash folder error, should not happens"); + } + } + } + mWorkingNote.markDeleted(true); + } + + private boolean isSyncMode() { + return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; + } + + public void onClockAlertChanged(long date, boolean set) { + /** + * User could set clock to an unsaved note, so before setting the + * alert clock, we should save the note first + */ + if (!mWorkingNote.existInDatabase()) { + saveNote(); + } + if (mWorkingNote.getNoteId() > 0) { + Intent intent = new Intent(this, AlarmReceiver.class); + intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId())); + PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); + AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); + showAlertHeader(); + if(!set) { + alarmManager.cancel(pendingIntent); + } else { + alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); + } + } else { + /** + * There is the condition that user has input nothing (the note is + * not worthy saving), we have no note id, remind the user that he + * should input something + */ + Log.e(TAG, "Clock alert setting error"); + showToast(R.string.error_note_empty_for_clock); + } + } + + public void onWidgetChanged() { + updateWidget(); + } + + public void onEditTextDelete(int index, String text) { + int childCount = mEditTextList.getChildCount(); + if (childCount == 1) { + return; + } + + for (int i = index + 1; i < childCount; i++) { + ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) + .setIndex(i - 1); + } + + mEditTextList.removeViewAt(index); + NoteEditText edit = null; + if(index == 0) { + edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById( + R.id.et_edit_text); + } else { + edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById( + R.id.et_edit_text); + } + int length = edit.length(); + edit.append(text); + edit.requestFocus(); + edit.setSelection(length); + } + + public void onEditTextEnter(int index, String text) { + /** + * Should not happen, check for debug + */ + if(index > mEditTextList.getChildCount()) { + Log.e(TAG, "Index out of mEditTextList boundrary, should not happen"); + } + + View view = getListItem(text, index); + mEditTextList.addView(view, index); + NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + edit.requestFocus(); + edit.setSelection(0); + for (int i = index + 1; i < mEditTextList.getChildCount(); i++) { + ((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text)) + .setIndex(i); + } + } + + private void switchToListMode(String text) { + mEditTextList.removeAllViews(); + String[] items = text.split("\n"); + int index = 0; + for (String item : items) { + if(!TextUtils.isEmpty(item)) { + mEditTextList.addView(getListItem(item, index)); + index++; + } + } + mEditTextList.addView(getListItem("", index)); + mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); + + mNoteEditor.setVisibility(View.GONE); + mEditTextList.setVisibility(View.VISIBLE); + } + + private Spannable getHighlightQueryResult(String fullText, String userQuery) { + SpannableString spannable = new SpannableString(fullText == null ? "" : fullText); + if (!TextUtils.isEmpty(userQuery)) { + mPattern = Pattern.compile(userQuery); + Matcher m = mPattern.matcher(fullText); + int start = 0; + while (m.find(start)) { + spannable.setSpan( + new BackgroundColorSpan(this.getResources().getColor( + R.color.user_query_highlight)), m.start(), m.end(), + Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + start = m.end(); + } + } + return spannable; + } + + private View getListItem(String item, int index) { + View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null); + final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); + CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item)); + cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + } else { + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + } + } + }); + + if (item.startsWith(TAG_CHECKED)) { + cb.setChecked(true); + edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + item = item.substring(TAG_CHECKED.length(), item.length()).trim(); + } else if (item.startsWith(TAG_UNCHECKED)) { + cb.setChecked(false); + edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); + item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); + } + + edit.setOnTextViewChangeListener(this); + edit.setIndex(index); + edit.setText(getHighlightQueryResult(item, mUserQuery)); + return view; + } + + public void onTextChange(int index, boolean hasText) { + if (index >= mEditTextList.getChildCount()) { + Log.e(TAG, "Wrong index, should not happen"); + return; + } + if(hasText) { + mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE); + } else { + mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE); + } + } + + public void onCheckListModeChanged(int oldMode, int newMode) { + if (newMode == TextNote.MODE_CHECK_LIST) { + switchToListMode(mNoteEditor.getText().toString()); + } else { + if (!getWorkingText()) { + mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", + "")); + } + mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); + mEditTextList.setVisibility(View.GONE); + mNoteEditor.setVisibility(View.VISIBLE); + } + } + + private boolean getWorkingText() { + boolean hasChecked = false; + if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < mEditTextList.getChildCount(); i++) { + View view = mEditTextList.getChildAt(i); + NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); + if (!TextUtils.isEmpty(edit.getText())) { + if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) { + sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n"); + hasChecked = true; + } else { + sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n"); + } + } + } + mWorkingNote.setWorkingText(sb.toString()); + } else { + mWorkingNote.setWorkingText(mNoteEditor.getText().toString()); + } + return hasChecked; + } + + private boolean saveNote() { + getWorkingText(); + boolean saved = mWorkingNote.saveNote(); + if (saved) { + /** + * There are two modes from List view to edit view, open one note, + * create/edit a node. Opening node requires to the original + * position in the list when back from edit view, while creating a + * new node requires to the top of the list. This code + * {@link #RESULT_OK} is used to identify the create/edit state + */ + setResult(RESULT_OK); + } + return saved; + } + + private void sendToDesktop() { + /** + * Before send message to home, we should make sure that current + * editing note is exists in databases. So, for new note, firstly + * save it + */ + if (!mWorkingNote.existInDatabase()) { + saveNote(); + } + + if (mWorkingNote.getNoteId() > 0) { + Intent sender = new Intent(); + Intent shortcutIntent = new Intent(this, NoteEditActivity.class); + shortcutIntent.setAction(Intent.ACTION_VIEW); + shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId()); + sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + sender.putExtra(Intent.EXTRA_SHORTCUT_NAME, + makeShortcutIconTitle(mWorkingNote.getContent())); + sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, + Intent.ShortcutIconResource.fromContext(this, R.drawable.icon_app)); + sender.putExtra("duplicate", true); + sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); + showToast(R.string.info_note_enter_desktop); + sendBroadcast(sender); + } else { + /** + * There is the condition that user has input nothing (the note is + * not worthy saving), we have no note id, remind the user that he + * should input something + */ + Log.e(TAG, "Send to desktop error"); + showToast(R.string.error_note_empty_for_send_to_desktop); + } + } + + private String makeShortcutIconTitle(String content) { + content = content.replace(TAG_CHECKED, ""); + content = content.replace(TAG_UNCHECKED, ""); + return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0, + SHORTCUT_ICON_TITLE_MAX_LEN) : content; + } + + private void showToast(int resId) { + showToast(resId, Toast.LENGTH_SHORT); + } + + private void showToast(int resId, int duration) { + Toast.makeText(this, resId, duration).show(); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditText.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditText.java new file mode 100644 index 0000000..2afe2a8 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteEditText.java @@ -0,0 +1,217 @@ +/* + * 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.graphics.Rect; +import android.text.Layout; +import android.text.Selection; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.style.URLSpan; +import android.util.AttributeSet; +import android.util.Log; +import android.view.ContextMenu; +import android.view.KeyEvent; +import android.view.MenuItem; +import android.view.MenuItem.OnMenuItemClickListener; +import android.view.MotionEvent; +import android.widget.EditText; + +import net.micode.notes.R; + +import java.util.HashMap; +import java.util.Map; + +public class NoteEditText extends EditText { + private static final String TAG = "NoteEditText"; + private int mIndex; + private int mSelectionStartBeforeDelete; + + private static final String SCHEME_TEL = "tel:" ; + private static final String SCHEME_HTTP = "http:" ; + private static final String SCHEME_EMAIL = "mailto:" ; + + private static final Map sSchemaActionResMap = new HashMap(); + static { + sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); + sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); + sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email); + } + + /** + * Call by the {@link NoteEditActivity} to delete or add edit text + */ + public interface OnTextViewChangeListener { + /** + * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens + * and the text is null + */ + void onEditTextDelete(int index, String text); + + /** + * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} + * happen + */ + void onEditTextEnter(int index, String text); + + /** + * Hide or show item option when text change + */ + void onTextChange(int index, boolean hasText); + } + + private OnTextViewChangeListener mOnTextViewChangeListener; + + public NoteEditText(Context context) { + super(context, null); + mIndex = 0; + } + + public void setIndex(int index) { + mIndex = index; + } + + public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { + mOnTextViewChangeListener = listener; + } + + public NoteEditText(Context context, AttributeSet attrs) { + super(context, attrs, android.R.attr.editTextStyle); + } + + public NoteEditText(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + // TODO Auto-generated constructor stub + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + + int x = (int) event.getX(); + int y = (int) event.getY(); + x -= getTotalPaddingLeft(); + y -= getTotalPaddingTop(); + x += getScrollX(); + y += getScrollY(); + + Layout layout = getLayout(); + int line = layout.getLineForVertical(y); + int off = layout.getOffsetForHorizontal(line, x); + Selection.setSelection(getText(), off); + break; + } + + return super.onTouchEvent(event); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + switch (keyCode) { + case KeyEvent.KEYCODE_ENTER: + if (mOnTextViewChangeListener != null) { + return false; + } + break; + case KeyEvent.KEYCODE_DEL: + mSelectionStartBeforeDelete = getSelectionStart(); + break; + default: + break; + } + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + switch(keyCode) { + case KeyEvent.KEYCODE_DEL: + if (mOnTextViewChangeListener != null) { + if (0 == mSelectionStartBeforeDelete && mIndex != 0) { + mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); + return true; + } + } else { + Log.d(TAG, "OnTextViewChangeListener was not seted"); + } + break; + case KeyEvent.KEYCODE_ENTER: + if (mOnTextViewChangeListener != null) { + int selectionStart = getSelectionStart(); + String text = getText().subSequence(selectionStart, length()).toString(); + setText(getText().subSequence(0, selectionStart)); + mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); + } else { + Log.d(TAG, "OnTextViewChangeListener was not seted"); + } + break; + default: + break; + } + return super.onKeyUp(keyCode, event); + } + + @Override + protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + if (mOnTextViewChangeListener != null) { + if (!focused && TextUtils.isEmpty(getText())) { + mOnTextViewChangeListener.onTextChange(mIndex, false); + } else { + mOnTextViewChangeListener.onTextChange(mIndex, true); + } + } + super.onFocusChanged(focused, direction, previouslyFocusedRect); + } + + @Override + protected void onCreateContextMenu(ContextMenu menu) { + if (getText() instanceof Spanned) { + int selStart = getSelectionStart(); + int selEnd = getSelectionEnd(); + + int min = Math.min(selStart, selEnd); + int max = Math.max(selStart, selEnd); + + final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); + if (urls.length == 1) { + int defaultResId = 0; + for(String schema: sSchemaActionResMap.keySet()) { + if(urls[0].getURL().indexOf(schema) >= 0) { + defaultResId = sSchemaActionResMap.get(schema); + break; + } + } + + if (defaultResId == 0) { + defaultResId = R.string.note_link_other; + } + + menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( + new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + // goto a new intent + urls[0].onClick(NoteEditText.this); + return true; + } + }); + } + } + super.onCreateContextMenu(menu); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteItemData.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteItemData.java new file mode 100644 index 0000000..0f5a878 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NoteItemData.java @@ -0,0 +1,224 @@ +/* + * 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.text.TextUtils; + +import net.micode.notes.data.Contact; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.tool.DataUtils; + + +public class NoteItemData { + static final String [] PROJECTION = new String [] { + NoteColumns.ID, + NoteColumns.ALERTED_DATE, + NoteColumns.BG_COLOR_ID, + NoteColumns.CREATED_DATE, + NoteColumns.HAS_ATTACHMENT, + NoteColumns.MODIFIED_DATE, + NoteColumns.NOTES_COUNT, + NoteColumns.PARENT_ID, + NoteColumns.SNIPPET, + NoteColumns.TYPE, + NoteColumns.WIDGET_ID, + NoteColumns.WIDGET_TYPE, + }; + + private static final int ID_COLUMN = 0; + private static final int ALERTED_DATE_COLUMN = 1; + private static final int BG_COLOR_ID_COLUMN = 2; + 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; + private static final int SNIPPET_COLUMN = 8; + private static final int TYPE_COLUMN = 9; + private static final int WIDGET_ID_COLUMN = 10; + private static final int WIDGET_TYPE_COLUMN = 11; + + private long mId; + private long mAlertDate; + private int mBgColorId; + private long mCreatedDate; + private boolean mHasAttachment; + private long mModifiedDate; + private int mNotesCount; + private long mParentId; + private String mSnippet; + private int mType; + private int mWidgetId; + 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); + mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN); + mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN); + 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); + 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); + mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN); + + mPhoneNumber = ""; + if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { + mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId); + if (!TextUtils.isEmpty(mPhoneNumber)) { + mName = Contact.getContact(context, mPhoneNumber); + if (mName == null) { + mName = mPhoneNumber; + } + } + } + + if (mName == null) { + mName = ""; + } + checkPostion(cursor); + } + + private void checkPostion(Cursor cursor) { + mIsLastItem = cursor.isLast() ? true : false; + mIsFirstItem = cursor.isFirst() ? true : false; + mIsOnlyOneItem = (cursor.getCount() == 1); + mIsMultiNotesFollowingFolder = false; + mIsOneNoteFollowingFolder = 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)) { + 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() { + return mId; + } + + public long getAlertDate() { + return mAlertDate; + } + + public long getCreatedDate() { + return mCreatedDate; + } + + public boolean hasAttachment() { + return mHasAttachment; + } + + public long getModifiedDate() { + return mModifiedDate; + } + + public int getBgColorId() { + return mBgColorId; + } + + public long getParentId() { + return mParentId; + } + + public int getNotesCount() { + return mNotesCount; + } + + public long getFolderId () { + return mParentId; + } + + public int getType() { + return mType; + } + + public int getWidgetType() { + return mWidgetType; + } + + public int getWidgetId() { + return mWidgetId; + } + + public String getSnippet() { + return mSnippet; + } + + public boolean hasAlert() { + return (mAlertDate > 0); + } + + public boolean isCallRecord() { + return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber)); + } + + public static int getNoteType(Cursor cursor) { + return cursor.getInt(TYPE_COLUMN); + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListActivity.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListActivity.java new file mode 100644 index 0000000..e843aec --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListActivity.java @@ -0,0 +1,954 @@ +/* + * 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.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.appwidget.AppWidgetManager; +import android.content.AsyncQueryHandler; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.Log; +import android.view.ActionMode; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.Display; +import android.view.HapticFeedbackConstants; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MenuItem.OnMenuItemClickListener; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnCreateContextMenuListener; +import android.view.View.OnTouchListener; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemLongClickListener; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.PopupMenu; +import android.widget.TextView; +import android.widget.Toast; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.remote.GTaskSyncService; +import net.micode.notes.model.WorkingNote; +import net.micode.notes.tool.BackupUtils; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.ResourceParser; +import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute; +import net.micode.notes.widget.NoteWidgetProvider_2x; +import net.micode.notes.widget.NoteWidgetProvider_4x; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashSet; + +public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { + private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; + + private static final int FOLDER_LIST_QUERY_TOKEN = 1; + + private static final int MENU_FOLDER_DELETE = 0; + + private static final int MENU_FOLDER_VIEW = 1; + + private static final int MENU_FOLDER_CHANGE_NAME = 2; + + private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; + + private enum ListEditState { + NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER + }; + + private ListEditState mState; + + private BackgroundQueryHandler mBackgroundQueryHandler; + + private NotesListAdapter mNotesListAdapter; + + private ListView mNotesListView; + + private Button mAddNewNote; + + private boolean mDispatch; + + private int mOriginY; + + private int mDispatchY; + + private TextView mTitleBar; + + private long mCurrentFolderId; + + private ContentResolver mContentResolver; + + private ModeCallback mModeCallBack; + + private static final String TAG = "NotesListActivity"; + + public static final int NOTES_LISTVIEW_SCROLL_RATE = 30; + + private NoteItemData mFocusNoteDataItem; + + private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; + + private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>" + + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" + " OR (" + + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + + NoteColumns.NOTES_COUNT + ">0)"; + + private final static int REQUEST_CODE_OPEN_NODE = 102; + private final static int REQUEST_CODE_NEW_NODE = 103; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.note_list); + initResources(); + + /** + * Insert an introduction when user firstly use this application + */ + setAppInfoFromRawRes(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == RESULT_OK + && (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE)) { + mNotesListAdapter.changeCursor(null); + } else { + super.onActivityResult(requestCode, resultCode, data); + } + } + + private void setAppInfoFromRawRes() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) { + StringBuilder sb = new StringBuilder(); + InputStream in = null; + try { + in = getResources().openRawResource(R.raw.introduction); + if (in != null) { + InputStreamReader isr = new InputStreamReader(in); + BufferedReader br = new BufferedReader(isr); + char [] buf = new char[1024]; + int len = 0; + while ((len = br.read(buf)) > 0) { + sb.append(buf, 0, len); + } + } else { + Log.e(TAG, "Read introduction file error"); + return; + } + } catch (IOException e) { + e.printStackTrace(); + return; + } finally { + if(in != null) { + try { + in.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + WorkingNote note = WorkingNote.createEmptyNote(this, Notes.ID_ROOT_FOLDER, + AppWidgetManager.INVALID_APPWIDGET_ID, Notes.TYPE_WIDGET_INVALIDE, + ResourceParser.RED); + note.setWorkingText(sb.toString()); + if (note.saveNote()) { + sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit(); + } else { + Log.e(TAG, "Save introduction note error"); + return; + } + } + } + + @Override + protected void onStart() { + super.onStart(); + startAsyncNotesListQuery(); + } + + private void initResources() { + mContentResolver = this.getContentResolver(); + mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver()); + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mNotesListView = (ListView) findViewById(R.id.notes_list); + mNotesListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.note_list_footer, null), + null, false); + mNotesListView.setOnItemClickListener(new OnListItemClickListener()); + mNotesListView.setOnItemLongClickListener(this); + mNotesListAdapter = new NotesListAdapter(this); + mNotesListView.setAdapter(mNotesListAdapter); + mAddNewNote = (Button) findViewById(R.id.btn_new_note); + mAddNewNote.setOnClickListener(this); + mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); + mDispatch = false; + mDispatchY = 0; + mOriginY = 0; + mTitleBar = (TextView) findViewById(R.id.tv_title_bar); + mState = ListEditState.NOTE_LIST; + mModeCallBack = new ModeCallback(); + } + + private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener { + private DropdownMenu mDropDownMenu; + private ActionMode mActionMode; + private MenuItem mMoveMenu; + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + getMenuInflater().inflate(R.menu.note_list_options, menu); + menu.findItem(R.id.delete).setOnMenuItemClickListener(this); + mMoveMenu = menu.findItem(R.id.move); + if (mFocusNoteDataItem.getParentId() == Notes.ID_CALL_RECORD_FOLDER + || DataUtils.getUserFolderCount(mContentResolver) == 0) { + mMoveMenu.setVisible(false); + } else { + mMoveMenu.setVisible(true); + mMoveMenu.setOnMenuItemClickListener(this); + } + mActionMode = mode; + mNotesListAdapter.setChoiceMode(true); + mNotesListView.setLongClickable(false); + mAddNewNote.setVisibility(View.GONE); + + View customView = LayoutInflater.from(NotesListActivity.this).inflate( + R.layout.note_list_dropdown_menu, null); + mode.setCustomView(customView); + mDropDownMenu = new DropdownMenu(NotesListActivity.this, + (Button) customView.findViewById(R.id.selection_menu), + R.menu.note_list_dropdown); + mDropDownMenu.setOnDropdownMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){ + public boolean onMenuItemClick(MenuItem item) { + mNotesListAdapter.selectAll(!mNotesListAdapter.isAllSelected()); + updateMenu(); + return true; + } + + }); + return true; + } + + private void updateMenu() { + int selectedCount = mNotesListAdapter.getSelectedCount(); + // Update dropdown menu + String format = getResources().getString(R.string.menu_select_title, selectedCount); + mDropDownMenu.setTitle(format); + MenuItem item = mDropDownMenu.findItem(R.id.action_select_all); + if (item != null) { + if (mNotesListAdapter.isAllSelected()) { + item.setChecked(true); + item.setTitle(R.string.menu_deselect_all); + } else { + item.setChecked(false); + item.setTitle(R.string.menu_select_all); + } + } + } + + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + // TODO Auto-generated method stub + return false; + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + // TODO Auto-generated method stub + return false; + } + + public void onDestroyActionMode(ActionMode mode) { + mNotesListAdapter.setChoiceMode(false); + mNotesListView.setLongClickable(true); + mAddNewNote.setVisibility(View.VISIBLE); + } + + public void finishActionMode() { + mActionMode.finish(); + } + + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, + boolean checked) { + mNotesListAdapter.setCheckedItem(position, checked); + updateMenu(); + } + + public boolean onMenuItemClick(MenuItem item) { + if (mNotesListAdapter.getSelectedCount() == 0) { + Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none), + Toast.LENGTH_SHORT).show(); + return true; + } + + switch (item.getItemId()) { + case R.id.delete: + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(getString(R.string.alert_title_delete)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_notes, + mNotesListAdapter.getSelectedCount())); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + batchDelete(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + break; + case R.id.move: + startQueryDestinationFolders(); + break; + default: + return false; + } + return true; + } + } + + private class NewNoteOnTouchListener implements OnTouchListener { + + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: { + Display display = getWindowManager().getDefaultDisplay(); + int screenHeight = display.getHeight(); + int newNoteViewHeight = mAddNewNote.getHeight(); + int start = screenHeight - newNoteViewHeight; + int eventY = start + (int) event.getY(); + /** + * Minus TitleBar's height + */ + if (mState == ListEditState.SUB_FOLDER) { + eventY -= mTitleBar.getHeight(); + start -= mTitleBar.getHeight(); + } + /** + * HACKME:When click the transparent part of "New Note" button, dispatch + * the event to the list view behind this button. The transparent part of + * "New Note" button could be expressed by formula y=-0.12x+94(Unit:pixel) + * and the line top of the button. The coordinate based on left of the "New + * Note" button. The 94 represents maximum height of the transparent part. + * Notice that, if the background of the button changes, the formula should + * also change. This is very bad, just for the UI designer's strong requirement. + */ + if (event.getY() < (event.getX() * (-0.12) + 94)) { + View view = mNotesListView.getChildAt(mNotesListView.getChildCount() - 1 + - mNotesListView.getFooterViewsCount()); + if (view != null && view.getBottom() > start + && (view.getTop() < (start + 94))) { + mOriginY = (int) event.getY(); + mDispatchY = eventY; + event.setLocation(event.getX(), mDispatchY); + mDispatch = true; + return mNotesListView.dispatchTouchEvent(event); + } + } + break; + } + case MotionEvent.ACTION_MOVE: { + if (mDispatch) { + mDispatchY += (int) event.getY() - mOriginY; + event.setLocation(event.getX(), mDispatchY); + return mNotesListView.dispatchTouchEvent(event); + } + break; + } + default: { + if (mDispatch) { + event.setLocation(event.getX(), mDispatchY); + mDispatch = false; + return mNotesListView.dispatchTouchEvent(event); + } + break; + } + } + return false; + } + + }; + + private void startAsyncNotesListQuery() { + String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION + : NORMAL_SELECTION; + mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null, + Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] { + String.valueOf(mCurrentFolderId) + }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); + } + + private final class BackgroundQueryHandler extends AsyncQueryHandler { + public BackgroundQueryHandler(ContentResolver contentResolver) { + super(contentResolver); + } + + @Override + protected void onQueryComplete(int token, Object cookie, Cursor cursor) { + switch (token) { + case FOLDER_NOTE_LIST_QUERY_TOKEN: + mNotesListAdapter.changeCursor(cursor); + break; + case FOLDER_LIST_QUERY_TOKEN: + if (cursor != null && cursor.getCount() > 0) { + showFolderListMenu(cursor); + } else { + Log.e(TAG, "Query folder failed"); + } + break; + default: + return; + } + } + } + + private void showFolderListMenu(Cursor cursor) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(R.string.menu_title_select_folder); + final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor); + builder.setAdapter(adapter, new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int which) { + DataUtils.batchMoveToFolder(mContentResolver, + mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which)); + Toast.makeText( + NotesListActivity.this, + getString(R.string.format_move_notes_to_folder, + mNotesListAdapter.getSelectedCount(), + adapter.getFolderName(NotesListActivity.this, which)), + Toast.LENGTH_SHORT).show(); + mModeCallBack.finishActionMode(); + } + }); + builder.show(); + } + + private void createNewNote() { + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_INSERT_OR_EDIT); + intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId); + this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); + } + + private void batchDelete() { + new AsyncTask>() { + protected HashSet doInBackground(Void... unused) { + HashSet widgets = mNotesListAdapter.getSelectedWidget(); + if (!isSyncMode()) { + // if not synced, delete notes directly + if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter + .getSelectedItemIds())) { + } else { + Log.e(TAG, "Delete notes error, should not happens"); + } + } else { + // in sync mode, we'll move the deleted note into the trash + // folder + if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter + .getSelectedItemIds(), Notes.ID_TRASH_FOLER)) { + Log.e(TAG, "Move notes to trash folder error, should not happens"); + } + } + return widgets; + } + + @Override + protected void onPostExecute(HashSet widgets) { + if (widgets != null) { + for (AppWidgetAttribute widget : widgets) { + if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID + && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { + updateWidget(widget.widgetId, widget.widgetType); + } + } + } + mModeCallBack.finishActionMode(); + } + }.execute(); + } + + private void deleteFolder(long folderId) { + if (folderId == Notes.ID_ROOT_FOLDER) { + Log.e(TAG, "Wrong folder id, should not happen " + folderId); + return; + } + + HashSet ids = new HashSet(); + ids.add(folderId); + HashSet widgets = DataUtils.getFolderNoteWidget(mContentResolver, + folderId); + if (!isSyncMode()) { + // if not synced, delete folder directly + DataUtils.batchDeleteNotes(mContentResolver, ids); + } else { + // in sync mode, we'll move the deleted folder into the trash folder + DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_TRASH_FOLER); + } + if (widgets != null) { + for (AppWidgetAttribute widget : widgets) { + if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID + && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { + updateWidget(widget.widgetId, widget.widgetType); + } + } + } + } + + private void openNode(NoteItemData data) { + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.putExtra(Intent.EXTRA_UID, data.getId()); + this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE); + } + + private void openFolder(NoteItemData data) { + mCurrentFolderId = data.getId(); + startAsyncNotesListQuery(); + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { + mState = ListEditState.CALL_RECORD_FOLDER; + mAddNewNote.setVisibility(View.GONE); + } else { + mState = ListEditState.SUB_FOLDER; + } + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { + mTitleBar.setText(R.string.call_record_folder_name); + } else { + mTitleBar.setText(data.getSnippet()); + } + mTitleBar.setVisibility(View.VISIBLE); + } + + public void onClick(View v) { + switch (v.getId()) { + case R.id.btn_new_note: + createNewNote(); + break; + default: + break; + } + } + + private void showSoftInput() { + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (inputMethodManager != null) { + inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + } + + private void hideSoftInput(View view) { + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + + private void showCreateOrModifyFolderDialog(final boolean create) { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null); + final EditText etName = (EditText) view.findViewById(R.id.et_foler_name); + showSoftInput(); + if (!create) { + if (mFocusNoteDataItem != null) { + etName.setText(mFocusNoteDataItem.getSnippet()); + builder.setTitle(getString(R.string.menu_folder_change_name)); + } else { + Log.e(TAG, "The long click data item is null"); + return; + } + } else { + etName.setText(""); + builder.setTitle(this.getString(R.string.menu_create_folder)); + } + + builder.setPositiveButton(android.R.string.ok, null); + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + hideSoftInput(etName); + } + }); + + final Dialog dialog = builder.setView(view).show(); + final Button positive = (Button)dialog.findViewById(android.R.id.button1); + positive.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + hideSoftInput(etName); + String name = etName.getText().toString(); + if (DataUtils.checkVisibleFolderName(mContentResolver, name)) { + Toast.makeText(NotesListActivity.this, getString(R.string.folder_exist, name), + Toast.LENGTH_LONG).show(); + etName.setSelection(0, etName.length()); + return; + } + if (!create) { + if (!TextUtils.isEmpty(name)) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.SNIPPET, name); + values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + values.put(NoteColumns.LOCAL_MODIFIED, 1); + mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID + + "=?", new String[] { + String.valueOf(mFocusNoteDataItem.getId()) + }); + } + } else if (!TextUtils.isEmpty(name)) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.SNIPPET, name); + values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + mContentResolver.insert(Notes.CONTENT_NOTE_URI, values); + } + dialog.dismiss(); + } + }); + + if (TextUtils.isEmpty(etName.getText())) { + positive.setEnabled(false); + } + /** + * When the name edit text is null, disable the positive button + */ + etName.addTextChangedListener(new TextWatcher() { + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // TODO Auto-generated method stub + + } + + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (TextUtils.isEmpty(etName.getText())) { + positive.setEnabled(false); + } else { + positive.setEnabled(true); + } + } + + public void afterTextChanged(Editable s) { + // TODO Auto-generated method stub + + } + }); + } + + @Override + public void onBackPressed() { + switch (mState) { + case SUB_FOLDER: + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mState = ListEditState.NOTE_LIST; + startAsyncNotesListQuery(); + mTitleBar.setVisibility(View.GONE); + break; + case CALL_RECORD_FOLDER: + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mState = ListEditState.NOTE_LIST; + mAddNewNote.setVisibility(View.VISIBLE); + mTitleBar.setVisibility(View.GONE); + startAsyncNotesListQuery(); + break; + case NOTE_LIST: + super.onBackPressed(); + break; + default: + break; + } + } + + private void updateWidget(int appWidgetId, int appWidgetType) { + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + if (appWidgetType == Notes.TYPE_WIDGET_2X) { + intent.setClass(this, NoteWidgetProvider_2x.class); + } else if (appWidgetType == Notes.TYPE_WIDGET_4X) { + intent.setClass(this, NoteWidgetProvider_4x.class); + } else { + Log.e(TAG, "Unspported widget type"); + return; + } + + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { + appWidgetId + }); + + sendBroadcast(intent); + setResult(RESULT_OK, intent); + } + + private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() { + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + if (mFocusNoteDataItem != null) { + menu.setHeaderTitle(mFocusNoteDataItem.getSnippet()); + menu.add(0, MENU_FOLDER_VIEW, 0, R.string.menu_folder_view); + menu.add(0, MENU_FOLDER_DELETE, 0, R.string.menu_folder_delete); + menu.add(0, MENU_FOLDER_CHANGE_NAME, 0, R.string.menu_folder_change_name); + } + } + }; + + @Override + public void onContextMenuClosed(Menu menu) { + if (mNotesListView != null) { + mNotesListView.setOnCreateContextMenuListener(null); + } + super.onContextMenuClosed(menu); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + if (mFocusNoteDataItem == null) { + Log.e(TAG, "The long click data item is null"); + return false; + } + switch (item.getItemId()) { + case MENU_FOLDER_VIEW: + openFolder(mFocusNoteDataItem); + break; + case MENU_FOLDER_DELETE: + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.alert_title_delete)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_folder)); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + deleteFolder(mFocusNoteDataItem.getId()); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + break; + case MENU_FOLDER_CHANGE_NAME: + showCreateOrModifyFolderDialog(false); + break; + default: + break; + } + + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + menu.clear(); + if (mState == ListEditState.NOTE_LIST) { + getMenuInflater().inflate(R.menu.note_list, menu); + // set sync or sync_cancel + menu.findItem(R.id.menu_sync).setTitle( + GTaskSyncService.isSyncing() ? R.string.menu_sync_cancel : R.string.menu_sync); + } else if (mState == ListEditState.SUB_FOLDER) { + getMenuInflater().inflate(R.menu.sub_folder, menu); + } else if (mState == ListEditState.CALL_RECORD_FOLDER) { + getMenuInflater().inflate(R.menu.call_record_folder, menu); + } else { + Log.e(TAG, "Wrong state:" + mState); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_new_folder: { + showCreateOrModifyFolderDialog(true); + break; + } + case R.id.menu_export_text: { + exportNoteToText(); + break; + } + case R.id.menu_sync: { + if (isSyncMode()) { + if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) { + GTaskSyncService.startSync(this); + } else { + GTaskSyncService.cancelSync(this); + } + } else { + startPreferenceActivity(); + } + break; + } + case R.id.menu_setting: { + startPreferenceActivity(); + break; + } + case R.id.menu_new_note: { + createNewNote(); + break; + } + case R.id.menu_search: + onSearchRequested(); + break; + default: + break; + } + return true; + } + + @Override + public boolean onSearchRequested() { + startSearch(null, false, null /* appData */, false); + return true; + } + + private void exportNoteToText() { + final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this); + new AsyncTask() { + + @Override + protected Integer doInBackground(Void... unused) { + return backup.exportToText(); + } + + @Override + protected void onPostExecute(Integer result) { + if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(NotesListActivity.this + .getString(R.string.failed_sdcard_export)); + builder.setMessage(NotesListActivity.this + .getString(R.string.error_sdcard_unmounted)); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } else if (result == BackupUtils.STATE_SUCCESS) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(NotesListActivity.this + .getString(R.string.success_sdcard_export)); + builder.setMessage(NotesListActivity.this.getString( + R.string.format_exported_file_location, backup + .getExportedTextFileName(), backup.getExportedTextFileDir())); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } else if (result == BackupUtils.STATE_SYSTEM_ERROR) { + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(NotesListActivity.this + .getString(R.string.failed_sdcard_export)); + builder.setMessage(NotesListActivity.this + .getString(R.string.error_sdcard_export)); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } + } + + }.execute(); + } + + private boolean isSyncMode() { + return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; + } + + private void startPreferenceActivity() { + Activity from = getParent() != null ? getParent() : this; + Intent intent = new Intent(from, NotesPreferenceActivity.class); + from.startActivityIfNeeded(intent, -1); + } + + private class OnListItemClickListener implements OnItemClickListener { + + public void onItemClick(AdapterView parent, View view, int position, long id) { + if (view instanceof NotesListItem) { + NoteItemData item = ((NotesListItem) view).getItemData(); + if (mNotesListAdapter.isInChoiceMode()) { + if (item.getType() == Notes.TYPE_NOTE) { + position = position - mNotesListView.getHeaderViewsCount(); + mModeCallBack.onItemCheckedStateChanged(null, position, id, + !mNotesListAdapter.isSelectedItem(position)); + } + return; + } + + switch (mState) { + case NOTE_LIST: + if (item.getType() == Notes.TYPE_FOLDER + || item.getType() == Notes.TYPE_SYSTEM) { + openFolder(item); + } else if (item.getType() == Notes.TYPE_NOTE) { + openNode(item); + } else { + Log.e(TAG, "Wrong note type in NOTE_LIST"); + } + break; + case SUB_FOLDER: + case CALL_RECORD_FOLDER: + if (item.getType() == Notes.TYPE_NOTE) { + openNode(item); + } else { + Log.e(TAG, "Wrong note type in SUB_FOLDER"); + } + break; + default: + break; + } + } + } + + } + + private void startQueryDestinationFolders() { + String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?"; + selection = (mState == ListEditState.NOTE_LIST) ? selection: + "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")"; + + mBackgroundQueryHandler.startQuery(FOLDER_LIST_QUERY_TOKEN, + null, + Notes.CONTENT_NOTE_URI, + FoldersListAdapter.PROJECTION, + selection, + new String[] { + String.valueOf(Notes.TYPE_FOLDER), + String.valueOf(Notes.ID_TRASH_FOLER), + String.valueOf(mCurrentFolderId) + }, + NoteColumns.MODIFIED_DATE + " DESC"); + } + + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + if (view instanceof NotesListItem) { + mFocusNoteDataItem = ((NotesListItem) view).getItemData(); + if (mFocusNoteDataItem.getType() == Notes.TYPE_NOTE && !mNotesListAdapter.isInChoiceMode()) { + if (mNotesListView.startActionMode(mModeCallBack) != null) { + mModeCallBack.onItemCheckedStateChanged(null, position, id, true); + mNotesListView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } else { + Log.e(TAG, "startActionMode fails"); + } + } else if (mFocusNoteDataItem.getType() == Notes.TYPE_FOLDER) { + mNotesListView.setOnCreateContextMenuListener(mFolderOnCreateContextMenuListener); + } + } + return false; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListAdapter.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListAdapter.java new file mode 100644 index 0000000..51c9cb9 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/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; + +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 { + private static final String TAG = "NotesListAdapter"; + private Context mContext; + private HashMap mSelectedIndex; + private int mNotesCount; + private boolean mChoiceMode; + + public static class AppWidgetAttribute { + 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) { + 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() { + 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"); + 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() { + 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) { + if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) { + mNotesCount++; + } + } else { + Log.e(TAG, "Invalid cursor"); + return; + } + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListItem.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListItem.java new file mode 100644 index 0000000..1221e80 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesListItem.java @@ -0,0 +1,122 @@ +/* + * 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.text.format.DateUtils; +import android.view.View; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.DataUtils; +import net.micode.notes.tool.ResourceParser.NoteItemBgResources; + + +public class NotesListItem extends LinearLayout { + private ImageView mAlert; + private TextView mTitle; + private TextView mTime; + private TextView mCallName; + private NoteItemData mItemData; + private CheckBox mCheckBox; + + public NotesListItem(Context context) { + super(context); + inflate(context, R.layout.note_item, this); + mAlert = (ImageView) findViewById(R.id.iv_alert_icon); + mTitle = (TextView) findViewById(R.id.tv_title); + mTime = (TextView) findViewById(R.id.tv_time); + mCallName = (TextView) findViewById(R.id.tv_name); + mCheckBox = (CheckBox) findViewById(android.R.id.checkbox); + } + + public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) { + if (choiceMode && data.getType() == Notes.TYPE_NOTE) { + mCheckBox.setVisibility(View.VISIBLE); + mCheckBox.setChecked(checked); + } else { + mCheckBox.setVisibility(View.GONE); + } + + mItemData = data; + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { + mCallName.setVisibility(View.GONE); + mAlert.setVisibility(View.VISIBLE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); + mTitle.setText(context.getString(R.string.call_record_folder_name) + + context.getString(R.string.format_folder_files_count, data.getNotesCount())); + mAlert.setImageResource(R.drawable.call_record); + } else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) { + mCallName.setVisibility(View.VISIBLE); + mCallName.setText(data.getCallName()); + mTitle.setTextAppearance(context,R.style.TextAppearanceSecondaryItem); + mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); + if (data.hasAlert()) { + mAlert.setImageResource(R.drawable.clock); + mAlert.setVisibility(View.VISIBLE); + } else { + mAlert.setVisibility(View.GONE); + } + } else { + mCallName.setVisibility(View.GONE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); + + if (data.getType() == Notes.TYPE_FOLDER) { + mTitle.setText(data.getSnippet() + + context.getString(R.string.format_folder_files_count, + data.getNotesCount())); + mAlert.setVisibility(View.GONE); + } else { + mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); + if (data.hasAlert()) { + mAlert.setImageResource(R.drawable.clock); + mAlert.setVisibility(View.VISIBLE); + } else { + mAlert.setVisibility(View.GONE); + } + } + } + mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate())); + + setBackground(data); + } + + private void setBackground(NoteItemData data) { + int id = data.getBgColorId(); + if (data.getType() == Notes.TYPE_NOTE) { + if (data.isSingle() || data.isOneFollowingFolder()) { + setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id)); + } else if (data.isLast()) { + setBackgroundResource(NoteItemBgResources.getNoteBgLastRes(id)); + } else if (data.isFirst() || data.isMultiFollowingFolder()) { + setBackgroundResource(NoteItemBgResources.getNoteBgFirstRes(id)); + } else { + setBackgroundResource(NoteItemBgResources.getNoteBgNormalRes(id)); + } + } else { + setBackgroundResource(NoteItemBgResources.getFolderBgRes()); + } + } + + public NoteItemData getItemData() { + return mItemData; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesPreferenceActivity.java b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesPreferenceActivity.java new file mode 100644 index 0000000..07c5f7e --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/ui/NotesPreferenceActivity.java @@ -0,0 +1,388 @@ +/* + * 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.accounts.Account; +import android.accounts.AccountManager; +import android.app.ActionBar; +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceActivity; +import android.preference.PreferenceCategory; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.remote.GTaskSyncService; + + +public class NotesPreferenceActivity extends PreferenceActivity { + public static final String PREFERENCE_NAME = "notes_preferences"; + + public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name"; + + public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time"; + + public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear"; + + private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key"; + + private static final String AUTHORITIES_FILTER_KEY = "authorities"; + + private PreferenceCategory mAccountCategory; + + private GTaskReceiver mReceiver; + + private Account[] mOriAccounts; + + private boolean mHasAddedAccount; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + + /* using the app icon for navigation */ + getActionBar().setDisplayHomeAsUpEnabled(true); + + addPreferencesFromResource(R.xml.preferences); + mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY); + mReceiver = new GTaskReceiver(); + IntentFilter filter = new IntentFilter(); + filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME); + registerReceiver(mReceiver, filter); + + mOriAccounts = null; + View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null); + getListView().addHeaderView(header, null, true); + } + + @Override + protected void onResume() { + super.onResume(); + + // need to set sync account automatically if user has added a new + // account + if (mHasAddedAccount) { + Account[] accounts = getGoogleAccounts(); + if (mOriAccounts != null && accounts.length > mOriAccounts.length) { + for (Account accountNew : accounts) { + boolean found = false; + for (Account accountOld : mOriAccounts) { + if (TextUtils.equals(accountOld.name, accountNew.name)) { + found = true; + break; + } + } + if (!found) { + setSyncAccount(accountNew.name); + break; + } + } + } + } + + refreshUI(); + } + + @Override + protected void onDestroy() { + if (mReceiver != null) { + unregisterReceiver(mReceiver); + } + super.onDestroy(); + } + + private void loadAccountPreference() { + mAccountCategory.removeAll(); + + Preference accountPref = new Preference(this); + final String defaultAccount = getSyncAccountName(this); + accountPref.setTitle(getString(R.string.preferences_account_title)); + accountPref.setSummary(getString(R.string.preferences_account_summary)); + accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + if (!GTaskSyncService.isSyncing()) { + if (TextUtils.isEmpty(defaultAccount)) { + // the first time to set account + showSelectAccountAlertDialog(); + } else { + // if the account has already been set, we need to promp + // user about the risk + showChangeAccountConfirmAlertDialog(); + } + } else { + Toast.makeText(NotesPreferenceActivity.this, + R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT) + .show(); + } + return true; + } + }); + + mAccountCategory.addPreference(accountPref); + } + + private void loadSyncButton() { + Button syncButton = (Button) findViewById(R.id.preference_sync_button); + TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview); + + // set button state + if (GTaskSyncService.isSyncing()) { + syncButton.setText(getString(R.string.preferences_button_sync_cancel)); + syncButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + GTaskSyncService.cancelSync(NotesPreferenceActivity.this); + } + }); + } else { + syncButton.setText(getString(R.string.preferences_button_sync_immediately)); + syncButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + GTaskSyncService.startSync(NotesPreferenceActivity.this); + } + }); + } + syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this))); + + // set last sync time + if (GTaskSyncService.isSyncing()) { + lastSyncTimeView.setText(GTaskSyncService.getProgressString()); + lastSyncTimeView.setVisibility(View.VISIBLE); + } else { + long lastSyncTime = getLastSyncTime(this); + if (lastSyncTime != 0) { + lastSyncTimeView.setText(getString(R.string.preferences_last_sync_time, + DateFormat.format(getString(R.string.preferences_last_sync_time_format), + lastSyncTime))); + lastSyncTimeView.setVisibility(View.VISIBLE); + } else { + lastSyncTimeView.setVisibility(View.GONE); + } + } + } + + private void refreshUI() { + loadAccountPreference(); + loadSyncButton(); + } + + private void showSelectAccountAlertDialog() { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); + + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); + TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); + titleTextView.setText(getString(R.string.preferences_dialog_select_account_title)); + TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); + subtitleTextView.setText(getString(R.string.preferences_dialog_select_account_tips)); + + dialogBuilder.setCustomTitle(titleView); + dialogBuilder.setPositiveButton(null, null); + + Account[] accounts = getGoogleAccounts(); + String defAccount = getSyncAccountName(this); + + mOriAccounts = accounts; + mHasAddedAccount = false; + + if (accounts.length > 0) { + CharSequence[] items = new CharSequence[accounts.length]; + final CharSequence[] itemMapping = items; + int checkedItem = -1; + int index = 0; + for (Account account : accounts) { + if (TextUtils.equals(account.name, defAccount)) { + checkedItem = index; + } + items[index++] = account.name; + } + dialogBuilder.setSingleChoiceItems(items, checkedItem, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + setSyncAccount(itemMapping[which].toString()); + dialog.dismiss(); + refreshUI(); + } + }); + } + + View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null); + dialogBuilder.setView(addAccountView); + + final AlertDialog dialog = dialogBuilder.show(); + addAccountView.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + mHasAddedAccount = true; + Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS"); + intent.putExtra(AUTHORITIES_FILTER_KEY, new String[] { + "gmail-ls" + }); + startActivityForResult(intent, -1); + dialog.dismiss(); + } + }); + } + + private void showChangeAccountConfirmAlertDialog() { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); + + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); + TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); + titleTextView.setText(getString(R.string.preferences_dialog_change_account_title, + getSyncAccountName(this))); + TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); + subtitleTextView.setText(getString(R.string.preferences_dialog_change_account_warn_msg)); + dialogBuilder.setCustomTitle(titleView); + + CharSequence[] menuItemArray = new CharSequence[] { + getString(R.string.preferences_menu_change_account), + getString(R.string.preferences_menu_remove_account), + getString(R.string.preferences_menu_cancel) + }; + dialogBuilder.setItems(menuItemArray, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + if (which == 0) { + showSelectAccountAlertDialog(); + } else if (which == 1) { + removeSyncAccount(); + refreshUI(); + } + } + }); + dialogBuilder.show(); + } + + private Account[] getGoogleAccounts() { + AccountManager accountManager = AccountManager.get(this); + return accountManager.getAccountsByType("com.google"); + } + + private void setSyncAccount(String account) { + if (!getSyncAccountName(this).equals(account)) { + SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = settings.edit(); + if (account != null) { + editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, account); + } else { + editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); + } + editor.commit(); + + // clean up last sync time + setLastSyncTime(this, 0); + + // clean up local gtask related info + new Thread(new Runnable() { + public void run() { + ContentValues values = new ContentValues(); + values.put(NoteColumns.GTASK_ID, ""); + values.put(NoteColumns.SYNC_ID, 0); + getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); + } + }).start(); + + Toast.makeText(NotesPreferenceActivity.this, + getString(R.string.preferences_toast_success_set_accout, account), + Toast.LENGTH_SHORT).show(); + } + } + + private void removeSyncAccount() { + SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = settings.edit(); + if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) { + editor.remove(PREFERENCE_SYNC_ACCOUNT_NAME); + } + if (settings.contains(PREFERENCE_LAST_SYNC_TIME)) { + editor.remove(PREFERENCE_LAST_SYNC_TIME); + } + editor.commit(); + + // clean up local gtask related info + new Thread(new Runnable() { + public void run() { + ContentValues values = new ContentValues(); + values.put(NoteColumns.GTASK_ID, ""); + values.put(NoteColumns.SYNC_ID, 0); + getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); + } + }).start(); + } + + public static String getSyncAccountName(Context context) { + SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, + Context.MODE_PRIVATE); + return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); + } + + public static void setLastSyncTime(Context context, long time) { + SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = settings.edit(); + editor.putLong(PREFERENCE_LAST_SYNC_TIME, time); + editor.commit(); + } + + public static long getLastSyncTime(Context context) { + SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, + Context.MODE_PRIVATE); + return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0); + } + + private class GTaskReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + refreshUI(); + if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) { + TextView syncStatus = (TextView) findViewById(R.id.prefenerece_sync_status_textview); + syncStatus.setText(intent + .getStringExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG)); + } + + } + } + + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + Intent intent = new Intent(this, NotesListActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + return true; + default: + return false; + } + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider.java b/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider.java new file mode 100644 index 0000000..ec6f819 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider.java @@ -0,0 +1,132 @@ +/* + * 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.widget; +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.util.Log; +import android.widget.RemoteViews; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.tool.ResourceParser; +import net.micode.notes.ui.NoteEditActivity; +import net.micode.notes.ui.NotesListActivity; + +public abstract class NoteWidgetProvider extends AppWidgetProvider { + public static final String [] PROJECTION = new String [] { + NoteColumns.ID, + NoteColumns.BG_COLOR_ID, + NoteColumns.SNIPPET + }; + + public static final int COLUMN_ID = 0; + public static final int COLUMN_BG_COLOR_ID = 1; + public static final int COLUMN_SNIPPET = 2; + + private static final String TAG = "NoteWidgetProvider"; + + @Override + public void onDeleted(Context context, int[] appWidgetIds) { + ContentValues values = new ContentValues(); + values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + for (int i = 0; i < appWidgetIds.length; i++) { + context.getContentResolver().update(Notes.CONTENT_NOTE_URI, + values, + NoteColumns.WIDGET_ID + "=?", + new String[] { String.valueOf(appWidgetIds[i])}); + } + } + + private Cursor getNoteWidgetInfo(Context context, int widgetId) { + return context.getContentResolver().query(Notes.CONTENT_NOTE_URI, + PROJECTION, + NoteColumns.WIDGET_ID + "=? AND " + NoteColumns.PARENT_ID + "<>?", + new String[] { String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER) }, + null); + } + + protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + update(context, appWidgetManager, appWidgetIds, false); + } + + private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds, + boolean privacyMode) { + for (int i = 0; i < appWidgetIds.length; i++) { + if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) { + int bgId = ResourceParser.getDefaultBgId(context); + String snippet = ""; + Intent intent = new Intent(context, NoteEditActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetIds[i]); + intent.putExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, getWidgetType()); + + Cursor c = getNoteWidgetInfo(context, appWidgetIds[i]); + if (c != null && c.moveToFirst()) { + if (c.getCount() > 1) { + Log.e(TAG, "Multiple message with same widget id:" + appWidgetIds[i]); + c.close(); + return; + } + snippet = c.getString(COLUMN_SNIPPET); + bgId = c.getInt(COLUMN_BG_COLOR_ID); + intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_ID)); + intent.setAction(Intent.ACTION_VIEW); + } else { + snippet = context.getResources().getString(R.string.widget_havenot_content); + intent.setAction(Intent.ACTION_INSERT_OR_EDIT); + } + + if (c != null) { + c.close(); + } + + RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId()); + rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId)); + intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId); + /** + * Generate the pending intent to start host for the widget + */ + PendingIntent pendingIntent = null; + if (privacyMode) { + rv.setTextViewText(R.id.widget_text, + context.getString(R.string.widget_under_visit_mode)); + pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], new Intent( + context, NotesListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); + } else { + rv.setTextViewText(R.id.widget_text, snippet); + pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent, + PendingIntent.FLAG_UPDATE_CURRENT); + } + + rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent); + appWidgetManager.updateAppWidget(appWidgetIds[i], rv); + } + } + } + + protected abstract int getBgResourceId(int bgId); + + protected abstract int getLayoutId(); + + protected abstract int getWidgetType(); +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_2x.java b/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_2x.java new file mode 100644 index 0000000..adcb2f7 --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_2x.java @@ -0,0 +1,47 @@ +/* + * 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.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.ResourceParser; + + +public class NoteWidgetProvider_2x extends NoteWidgetProvider { + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + super.update(context, appWidgetManager, appWidgetIds); + } + + @Override + protected int getLayoutId() { + return R.layout.widget_2x; + } + + @Override + protected int getBgResourceId(int bgId) { + return ResourceParser.WidgetBgResources.getWidget2xBgResource(bgId); + } + + @Override + protected int getWidgetType() { + return Notes.TYPE_WIDGET_2X; + } +} diff --git a/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_4x.java b/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_4x.java new file mode 100644 index 0000000..c12a02e --- /dev/null +++ b/src/Notesmaster/app/src/test/java/net/micode/notes/widget/NoteWidgetProvider_4x.java @@ -0,0 +1,46 @@ +/* + * 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.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.tool.ResourceParser; + + +public class NoteWidgetProvider_4x extends NoteWidgetProvider { + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + super.update(context, appWidgetManager, appWidgetIds); + } + + protected int getLayoutId() { + return R.layout.widget_4x; + } + + @Override + protected int getBgResourceId(int bgId) { + return ResourceParser.WidgetBgResources.getWidget4xBgResource(bgId); + } + + @Override + protected int getWidgetType() { + return Notes.TYPE_WIDGET_4X; + } +} diff --git a/src/Notesmaster/gradle.properties b/src/Notesmaster/gradle.properties index fd5ffa1..00d252e 100644 --- a/src/Notesmaster/gradle.properties +++ b/src/Notesmaster/gradle.properties @@ -19,4 +19,4 @@ android.useAndroidX=true # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library android.nonTransitiveRClass=true -android.nonFinalResIds=false +android.nonFinalResIds=false \ No newline at end of file diff --git a/src/Notesmaster/gradle/libs.versions.toml b/src/Notesmaster/gradle/libs.versions.toml index bdc2b99..08c8f02 100644 --- a/src/Notesmaster/gradle/libs.versions.toml +++ b/src/Notesmaster/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.6.0" +agp = "8.7.2" junit = "4.13.2" junitVersion = "1.1.5" espressoCore = "3.5.1" diff --git a/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties b/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties index 6758f3d..b06ea38 100644 --- a/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties +++ b/src/Notesmaster/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Nov 07 23:02:35 CST 2024 +#Thu Nov 14 16:44:27 CST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists

    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 diff --git a/doc/小米便签开源代码的泛读报告111.docx b/doc/小米便签开源代码的泛读报告111.docx deleted file mode 100644 index 7b7b4e2fcb24f52c6f46b80d6822ee8fd8770231..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 491392 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