From 195e9993531364008b2ddcaf5f24166afb93751a Mon Sep 17 00:00:00 2001 From: huliaoying Date: Wed, 31 May 2023 10:55:20 +0800 Subject: [PATCH] add tes --- .gitignore | 37 + LICENSE | 201 ++++ README.md | 27 + app/build.gradle | 22 + app/src/main/AndroidManifest.xml | 152 +++ .../java/net/micode/notes/data/Contact.java | 86 ++ .../java/net/micode/notes/data/Notes.java | 279 +++++ .../notes/data/NotesDatabaseHelper.java | 402 +++++++ .../net/micode/notes/data/NotesProvider.java | 378 ++++++ .../net/micode/notes/gtask/data/MetaData.java | 103 ++ .../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 | 124 ++ .../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 | 879 ++++++++++++++ .../net/micode/notes/ui/NoteEditText.java | 217 ++++ .../net/micode/notes/ui/NoteItemData.java | 224 ++++ .../micode/notes/ui/NotesListActivity.java | 1017 +++++++++++++++++ .../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/res/color/primary_text_dark.xml | 22 + .../main/res/color/secondary_text_dark.xml | 20 + .../main/res/drawable-hdpi/background1.png | Bin 0 -> 1825878 bytes .../main/res/drawable-hdpi/background2.jpg | Bin 0 -> 1536065 bytes .../main/res/drawable-hdpi/background3.jpg | Bin 0 -> 105492 bytes .../res/drawable-hdpi/bg_btn_set_color.png | Bin 0 -> 3588 bytes .../res/drawable-hdpi/bg_color_btn_mask.png | Bin 0 -> 245 bytes .../main/res/drawable-hdpi/call_record.png | Bin 0 -> 3533 bytes app/src/main/res/drawable-hdpi/clock.png | Bin 0 -> 3958 bytes app/src/main/res/drawable-hdpi/delete.png | Bin 0 -> 3490 bytes .../res/drawable-hdpi/dropdown_icon.9.png | Bin 0 -> 443 bytes .../main/res/drawable-hdpi/edit_blue.9.png | Bin 0 -> 3524 bytes .../main/res/drawable-hdpi/edit_green.9.png | Bin 0 -> 3565 bytes app/src/main/res/drawable-hdpi/edit_red.9.png | Bin 0 -> 3458 bytes .../res/drawable-hdpi/edit_title_blue.9.png | Bin 0 -> 5100 bytes .../res/drawable-hdpi/edit_title_green.9.png | Bin 0 -> 5627 bytes .../res/drawable-hdpi/edit_title_red.9.png | Bin 0 -> 5061 bytes .../res/drawable-hdpi/edit_title_white.9.png | Bin 0 -> 3866 bytes .../res/drawable-hdpi/edit_title_yellow.9.png | Bin 0 -> 6000 bytes .../main/res/drawable-hdpi/edit_white.9.png | Bin 0 -> 3441 bytes .../main/res/drawable-hdpi/edit_yellow.9.png | Bin 0 -> 3634 bytes app/src/main/res/drawable-hdpi/font_large.png | Bin 0 -> 3161 bytes .../main/res/drawable-hdpi/font_normal.png | Bin 0 -> 3097 bytes .../drawable-hdpi/font_size_selector_bg.9.png | Bin 0 -> 4101 bytes app/src/main/res/drawable-hdpi/font_small.png | Bin 0 -> 3099 bytes app/src/main/res/drawable-hdpi/font_super.png | Bin 0 -> 3188 bytes .../main/res/drawable-hdpi/ic_menu_more.png | Bin 0 -> 144 bytes .../res/drawable-hdpi/ic_menu_more_dark.png | Bin 0 -> 148 bytes app/src/main/res/drawable-hdpi/icon_app.png | Bin 0 -> 6887 bytes .../res/drawable-hdpi/list_background.png | Bin 0 -> 567323 bytes .../res/drawable-hdpi/list_blue_down.9.png | Bin 0 -> 4361 bytes .../res/drawable-hdpi/list_blue_middle.9.png | Bin 0 -> 3099 bytes .../res/drawable-hdpi/list_blue_single.9.png | Bin 0 -> 4618 bytes .../main/res/drawable-hdpi/list_blue_up.9.png | Bin 0 -> 3301 bytes .../main/res/drawable-hdpi/list_folder.9.png | Bin 0 -> 5608 bytes .../res/drawable-hdpi/list_footer_bg.9.png | Bin 0 -> 2837 bytes .../res/drawable-hdpi/list_green_down.9.png | Bin 0 -> 4488 bytes .../res/drawable-hdpi/list_green_middle.9.png | Bin 0 -> 3179 bytes .../res/drawable-hdpi/list_green_single.9.png | Bin 0 -> 4728 bytes .../res/drawable-hdpi/list_green_up.9.png | Bin 0 -> 3351 bytes .../res/drawable-hdpi/list_red_down.9.png | Bin 0 -> 4307 bytes .../res/drawable-hdpi/list_red_middle.9.png | Bin 0 -> 3075 bytes .../res/drawable-hdpi/list_red_single.9.png | Bin 0 -> 4565 bytes .../main/res/drawable-hdpi/list_red_up.9.png | Bin 0 -> 3277 bytes .../res/drawable-hdpi/list_white_down.9.png | Bin 0 -> 4305 bytes .../res/drawable-hdpi/list_white_middle.9.png | Bin 0 -> 3042 bytes .../res/drawable-hdpi/list_white_single.9.png | Bin 0 -> 4546 bytes .../res/drawable-hdpi/list_white_up.9.png | Bin 0 -> 3220 bytes .../res/drawable-hdpi/list_yellow_down.9.png | Bin 0 -> 4420 bytes .../drawable-hdpi/list_yellow_middle.9.png | Bin 0 -> 3150 bytes .../drawable-hdpi/list_yellow_single.9.png | Bin 0 -> 4670 bytes .../res/drawable-hdpi/list_yellow_up.9.png | Bin 0 -> 3335 bytes .../main/res/drawable-hdpi/menu_delete.png | Bin 0 -> 3426 bytes app/src/main/res/drawable-hdpi/menu_move.png | Bin 0 -> 3294 bytes .../res/drawable-hdpi/new_note_normal.png | Bin 0 -> 89221 bytes .../res/drawable-hdpi/new_note_pressed.png | Bin 0 -> 90126 bytes .../note_edit_color_selector_panel.png | Bin 0 -> 7030 bytes .../main/res/drawable-hdpi/notification.png | Bin 0 -> 3107 bytes .../main/res/drawable-hdpi/search_result.png | Bin 0 -> 3030 bytes app/src/main/res/drawable-hdpi/selected.png | Bin 0 -> 4959 bytes .../main/res/drawable-hdpi/title_alert.png | Bin 0 -> 3696 bytes .../main/res/drawable-hdpi/title_bar_bg.9.png | Bin 0 -> 5970 bytes .../main/res/drawable-hdpi/widget_2x_blue.png | Bin 0 -> 1946 bytes .../res/drawable-hdpi/widget_2x_green.png | Bin 0 -> 1954 bytes .../main/res/drawable-hdpi/widget_2x_red.png | Bin 0 -> 1892 bytes .../res/drawable-hdpi/widget_2x_white.png | Bin 0 -> 1901 bytes .../res/drawable-hdpi/widget_2x_yellow.png | Bin 0 -> 1978 bytes .../main/res/drawable-hdpi/widget_4x_blue.png | Bin 0 -> 4165 bytes .../res/drawable-hdpi/widget_4x_green.png | Bin 0 -> 4192 bytes .../main/res/drawable-hdpi/widget_4x_red.png | Bin 0 -> 4223 bytes .../res/drawable-hdpi/widget_4x_white.png | Bin 0 -> 4106 bytes .../res/drawable-hdpi/widget_4x_yellow.png | Bin 0 -> 4199 bytes app/src/main/res/drawable/new_note.xml | 23 + .../main/res/layout/account_dialog_title.xml | 43 + app/src/main/res/layout/add_account_text.xml | 32 + app/src/main/res/layout/datetime_picker.xml | 56 + app/src/main/res/layout/dialog_edit_text.xml | 23 + app/src/main/res/layout/folder_list_item.xml | 29 + app/src/main/res/layout/note_edit.xml | 420 +++++++ .../main/res/layout/note_edit_list_item.xml | 39 + app/src/main/res/layout/note_item.xml | 78 ++ app/src/main/res/layout/note_list.xml | 69 ++ .../res/layout/note_list_dropdown_menu.xml | 32 + app/src/main/res/layout/note_list_footer.xml | 24 + app/src/main/res/layout/settings_header.xml | 41 + app/src/main/res/layout/widget_2x.xml | 37 + app/src/main/res/layout/widget_4x.xml | 39 + app/src/main/res/menu/call_note_edit.xml | 48 + app/src/main/res/menu/call_record_folder.xml | 23 + app/src/main/res/menu/note_edit.xml | 52 + app/src/main/res/menu/note_list.xml | 54 + app/src/main/res/menu/note_list_dropdown.xml | 20 + app/src/main/res/menu/note_list_options.xml | 31 + app/src/main/res/menu/sub_folder.xml | 24 + app/src/main/res/raw-zh-rCN/introduction | 6 + app/src/main/res/raw/introduction | 1 + app/src/main/res/values-zh-rCN/arrays.xml | 23 + app/src/main/res/values-zh-rCN/strings.xml | 126 ++ app/src/main/res/values-zh-rTW/arrays.xml | 23 + app/src/main/res/values-zh-rTW/strings.xml | 127 ++ app/src/main/res/values/arrays.xml | 31 + app/src/main/res/values/colors.xml | 20 + app/src/main/res/values/dimens.xml | 24 + app/src/main/res/values/strings.xml | 141 +++ app/src/main/res/values/styles.xml | 69 ++ app/src/main/res/xml/preferences.xml | 30 + app/src/main/res/xml/searchable.xml | 27 + app/src/main/res/xml/widget_2x_info.xml | 23 + app/src/main/res/xml/widget_4x_info.xml | 23 + build.gradle | 19 + gradle.properties | 16 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 160 +++ gradlew.bat | 90 ++ import-summary.txt | 36 + settings.gradle | 1 + 161 files changed, 12958 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 app/build.gradle create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/net/micode/notes/data/Contact.java create mode 100644 app/src/main/java/net/micode/notes/data/Notes.java create mode 100644 app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java create mode 100644 app/src/main/java/net/micode/notes/data/NotesProvider.java create mode 100644 app/src/main/java/net/micode/notes/gtask/data/MetaData.java create mode 100644 app/src/main/java/net/micode/notes/gtask/data/Node.java create mode 100644 app/src/main/java/net/micode/notes/gtask/data/SqlData.java create mode 100644 app/src/main/java/net/micode/notes/gtask/data/SqlNote.java create mode 100644 app/src/main/java/net/micode/notes/gtask/data/Task.java create mode 100644 app/src/main/java/net/micode/notes/gtask/data/TaskList.java create mode 100644 app/src/main/java/net/micode/notes/gtask/exception/ActionFailureException.java create mode 100644 app/src/main/java/net/micode/notes/gtask/exception/NetworkFailureException.java create mode 100644 app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java create mode 100644 app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java create mode 100644 app/src/main/java/net/micode/notes/gtask/remote/GTaskManager.java create mode 100644 app/src/main/java/net/micode/notes/gtask/remote/GTaskSyncService.java create mode 100644 app/src/main/java/net/micode/notes/model/Note.java create mode 100644 app/src/main/java/net/micode/notes/model/WorkingNote.java create mode 100644 app/src/main/java/net/micode/notes/tool/BackupUtils.java create mode 100644 app/src/main/java/net/micode/notes/tool/DataUtils.java create mode 100644 app/src/main/java/net/micode/notes/tool/GTaskStringUtils.java create mode 100644 app/src/main/java/net/micode/notes/tool/ResourceParser.java create mode 100644 app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java create mode 100644 app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java create mode 100644 app/src/main/java/net/micode/notes/ui/AlarmReceiver.java create mode 100644 app/src/main/java/net/micode/notes/ui/DateTimePicker.java create mode 100644 app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java create mode 100644 app/src/main/java/net/micode/notes/ui/DropdownMenu.java create mode 100644 app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java create mode 100644 app/src/main/java/net/micode/notes/ui/NoteEditActivity.java create mode 100644 app/src/main/java/net/micode/notes/ui/NoteEditText.java create mode 100644 app/src/main/java/net/micode/notes/ui/NoteItemData.java create mode 100644 app/src/main/java/net/micode/notes/ui/NotesListActivity.java create mode 100644 app/src/main/java/net/micode/notes/ui/NotesListAdapter.java create mode 100644 app/src/main/java/net/micode/notes/ui/NotesListItem.java create mode 100644 app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java create mode 100644 app/src/main/java/net/micode/notes/widget/NoteWidgetProvider.java create mode 100644 app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_2x.java create mode 100644 app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_4x.java create mode 100644 app/src/main/res/color/primary_text_dark.xml create mode 100644 app/src/main/res/color/secondary_text_dark.xml create mode 100644 app/src/main/res/drawable-hdpi/background1.png create mode 100644 app/src/main/res/drawable-hdpi/background2.jpg create mode 100644 app/src/main/res/drawable-hdpi/background3.jpg create mode 100644 app/src/main/res/drawable-hdpi/bg_btn_set_color.png create mode 100644 app/src/main/res/drawable-hdpi/bg_color_btn_mask.png create mode 100644 app/src/main/res/drawable-hdpi/call_record.png create mode 100644 app/src/main/res/drawable-hdpi/clock.png create mode 100644 app/src/main/res/drawable-hdpi/delete.png create mode 100644 app/src/main/res/drawable-hdpi/dropdown_icon.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_blue.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_green.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_red.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_title_blue.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_title_green.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_title_red.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_title_white.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_title_yellow.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_white.9.png create mode 100644 app/src/main/res/drawable-hdpi/edit_yellow.9.png create mode 100644 app/src/main/res/drawable-hdpi/font_large.png create mode 100644 app/src/main/res/drawable-hdpi/font_normal.png create mode 100644 app/src/main/res/drawable-hdpi/font_size_selector_bg.9.png create mode 100644 app/src/main/res/drawable-hdpi/font_small.png create mode 100644 app/src/main/res/drawable-hdpi/font_super.png create mode 100644 app/src/main/res/drawable-hdpi/ic_menu_more.png create mode 100644 app/src/main/res/drawable-hdpi/ic_menu_more_dark.png create mode 100644 app/src/main/res/drawable-hdpi/icon_app.png create mode 100644 app/src/main/res/drawable-hdpi/list_background.png create mode 100644 app/src/main/res/drawable-hdpi/list_blue_down.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_blue_middle.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_blue_single.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_blue_up.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_folder.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_footer_bg.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_green_down.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_green_middle.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_green_single.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_green_up.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_red_down.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_red_middle.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_red_single.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_red_up.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_white_down.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_white_middle.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_white_single.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_white_up.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_yellow_down.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_yellow_middle.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_yellow_single.9.png create mode 100644 app/src/main/res/drawable-hdpi/list_yellow_up.9.png create mode 100644 app/src/main/res/drawable-hdpi/menu_delete.png create mode 100644 app/src/main/res/drawable-hdpi/menu_move.png create mode 100644 app/src/main/res/drawable-hdpi/new_note_normal.png create mode 100644 app/src/main/res/drawable-hdpi/new_note_pressed.png create mode 100644 app/src/main/res/drawable-hdpi/note_edit_color_selector_panel.png create mode 100644 app/src/main/res/drawable-hdpi/notification.png create mode 100644 app/src/main/res/drawable-hdpi/search_result.png create mode 100644 app/src/main/res/drawable-hdpi/selected.png create mode 100644 app/src/main/res/drawable-hdpi/title_alert.png create mode 100644 app/src/main/res/drawable-hdpi/title_bar_bg.9.png create mode 100644 app/src/main/res/drawable-hdpi/widget_2x_blue.png create mode 100644 app/src/main/res/drawable-hdpi/widget_2x_green.png create mode 100644 app/src/main/res/drawable-hdpi/widget_2x_red.png create mode 100644 app/src/main/res/drawable-hdpi/widget_2x_white.png create mode 100644 app/src/main/res/drawable-hdpi/widget_2x_yellow.png create mode 100644 app/src/main/res/drawable-hdpi/widget_4x_blue.png create mode 100644 app/src/main/res/drawable-hdpi/widget_4x_green.png create mode 100644 app/src/main/res/drawable-hdpi/widget_4x_red.png create mode 100644 app/src/main/res/drawable-hdpi/widget_4x_white.png create mode 100644 app/src/main/res/drawable-hdpi/widget_4x_yellow.png create mode 100644 app/src/main/res/drawable/new_note.xml create mode 100644 app/src/main/res/layout/account_dialog_title.xml create mode 100644 app/src/main/res/layout/add_account_text.xml create mode 100644 app/src/main/res/layout/datetime_picker.xml create mode 100644 app/src/main/res/layout/dialog_edit_text.xml create mode 100644 app/src/main/res/layout/folder_list_item.xml create mode 100644 app/src/main/res/layout/note_edit.xml create mode 100644 app/src/main/res/layout/note_edit_list_item.xml create mode 100644 app/src/main/res/layout/note_item.xml create mode 100644 app/src/main/res/layout/note_list.xml create mode 100644 app/src/main/res/layout/note_list_dropdown_menu.xml create mode 100644 app/src/main/res/layout/note_list_footer.xml create mode 100644 app/src/main/res/layout/settings_header.xml create mode 100644 app/src/main/res/layout/widget_2x.xml create mode 100644 app/src/main/res/layout/widget_4x.xml create mode 100644 app/src/main/res/menu/call_note_edit.xml create mode 100644 app/src/main/res/menu/call_record_folder.xml create mode 100644 app/src/main/res/menu/note_edit.xml create mode 100644 app/src/main/res/menu/note_list.xml create mode 100644 app/src/main/res/menu/note_list_dropdown.xml create mode 100644 app/src/main/res/menu/note_list_options.xml create mode 100644 app/src/main/res/menu/sub_folder.xml create mode 100644 app/src/main/res/raw-zh-rCN/introduction create mode 100644 app/src/main/res/raw/introduction create mode 100644 app/src/main/res/values-zh-rCN/arrays.xml create mode 100644 app/src/main/res/values-zh-rCN/strings.xml create mode 100644 app/src/main/res/values-zh-rTW/arrays.xml create mode 100644 app/src/main/res/values-zh-rTW/strings.xml create mode 100644 app/src/main/res/values/arrays.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/xml/preferences.xml create mode 100644 app/src/main/res/xml/searchable.xml create mode 100644 app/src/main/res/xml/widget_2x_info.xml create mode 100644 app/src/main/res/xml/widget_4x_info.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 import-summary.txt create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba4cbe0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +*.iml + +.DS_Store + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Intellij +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/dictionaries +.idea/libraries +.idea/ + +# Keystore files +*.jks + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md index a6ed909..c812bd1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ +<<<<<<< HEAD # note +======= +# MiNotes +[中文] + +1. MiCode便签是小米便签的社区开源版,由MIUI团队(www.miui.com) 发起并贡献第一批代码,遵循NOTICE文件所描述的开源协议, + 今后为MiCode社区(www.micode.net) 拥有,并由社区发布和维护。 + +2. Bug反馈和跟踪,请访问Github, + https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open + +3. 功能建议和综合讨论,请访问MiCode, + http://micode.net/forum.php?mod=forumdisplay&fid=38 + + +[English] + +1. MiCode Notes is open source edition of XM notepad, it's first initiated and sponsored by MIUI team (www.miui.com). + It's opened under license described by NOTICE file. It's owned by the MiCode community (www.micode.net). In future, + the MiCode community will release and maintain this project. + +2. Regarding issue tracking, please visit Github, + https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open + +3. Regarding feature request and general discussion, please visit Micode forum, + http://micode.net/forum.php?mod=forumdisplay&fid=38 +>>>>>>> e4d75ee (add a) diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..6cf7abb --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 33 + buildToolsVersion "25.0.1" + aaptOptions.cruncherEnabled = false + aaptOptions.useNewCruncher = false + useLibrary 'org.apache.http.legacy' + defaultConfig { + applicationId "net.micode.notes" + minSdkVersion 14 + targetSdkVersion 33 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } + android{ useLibrary 'org.apache.http.legacy' } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a2802f6 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/net/micode/notes/data/Contact.java b/app/src/main/java/net/micode/notes/data/Contact.java new file mode 100644 index 0000000..4a236b5 --- /dev/null +++ b/app/src/main/java/net/micode/notes/data/Contact.java @@ -0,0 +1,86 @@ +/* + * 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 { + // 声明一个用于缓存联系人的HashMap + private static HashMap sContactCache; + // 声明日志输出的TAG + private static final String TAG = "Contact"; + // 定义查询联系人的选择条件,使用占位符 "?" 和 "IN" 子句 + 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 = '+')"; + + /** + * 获取联系人名称 + * @param context 上下文环境 + * @param phoneNumber 联系人的电话号码 + * @return 联系人的名称,如果找不到返回null + */ + public static String getContact(Context context, String phoneNumber) { + // 如果联系人缓存为空,则创建一个新的HashMap + if(sContactCache == null) { + sContactCache = new HashMap(); + } + + // 如果联系人缓存中已经存在该电话号码的联系人,则直接返回联系人名称 + if(sContactCache.containsKey(phoneNumber)) { + return sContactCache.get(phoneNumber); + } + + // 使用PhoneNumberUtils工具类将电话号码转换为拨号最小匹配 + 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 { + // 如果找不到联系人,则打印日志并返回null + Log.d(TAG, "No contact matched with number:" + phoneNumber); + return null; + } + } +} diff --git a/app/src/main/java/net/micode/notes/data/Notes.java b/app/src/main/java/net/micode/notes/data/Notes.java new file mode 100644 index 0000000..f240604 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java b/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java new file mode 100644 index 0000000..102c852 --- /dev/null +++ b/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java @@ -0,0 +1,402 @@ +/* + * 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";// 日志tag + + private static NotesDatabaseHelper mInstance; // 数据库帮助类实例 + // 创建笔记数据表的SQL语句 + 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" + + ")"; + // 创建笔记内容数据表的SQL语句 + 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 ''" + + ")"; + /** + *创建笔记在SQL中的Id + */ + 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} + * 在插入类型为 {@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 + * 在类型为 {@link DataConstants#NOTE} 的数据更新时更新笔记的内容 + */ + 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 + * 在类型为 {@link DataConstants#NOTE} 的数据删除时更新笔记的内容 + */ + 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"); + } + /** + * 重新创建笔记表的触发器 + * @param db 数据库对象 + */ + 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); + // 创建将笔记移动到垃圾桶时的触发器 + } + /** + + 创建系统文件夹 + + @param db 数据库对象 + */ + private void createSystemFolder(SQLiteDatabase db) { + ContentValues values = new ContentValues(); + + /** + + 通话记录文件夹 + */ + values.put(NoteColumns.ID, Notes.ID_CALL_RECORD_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + + 根文件夹,即默认文件夹 + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + + 临时文件夹,用于移动笔记 + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + + 创建垃圾桶文件夹 + */ + 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); // 在数据表上创建笔记 ID 索引 + 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; // 是否跳过版本 2 + + if (oldVersion == 1) { + upgradeToV2(db); // 升级到版本 2 + skipV2 = true; // 标记跳过版本 2(因为版本 2 升级包含在版本 3 升级中) + oldVersion++; // 版本号加 1 + } + + if (oldVersion == 2 && !skipV2) { + upgradeToV3(db); // 升级到版本 3 + reCreateTriggers = true; // 标记需要重新创建触发器 + oldVersion++; // 版本号加 1 + } + + if (oldVersion == 3) { + upgradeToV4(db); // 升级到版本 4 + oldVersion++; // 版本号加 1 + } + + 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/app/src/main/java/net/micode/notes/data/NotesProvider.java b/app/src/main/java/net/micode/notes/data/NotesProvider.java new file mode 100644 index 0000000..6eb4846 --- /dev/null +++ b/app/src/main/java/net/micode/notes/data/NotesProvider.java @@ -0,0 +1,378 @@ +/* + * 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 { + // 声明一个 UriMatcher 对象,用于匹配 Uri 和对应的代码 + private static final UriMatcher mMatcher; + + private NotesDatabaseHelper mHelper; + + private static final String TAG = "NotesProvider"; + // 声明一些常量,用于标识 Uri 匹配的类型 + 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; + // 初始化 UriMatcher 对象,将 Uri 和对应的类型添加到 UriMatcher 中 + 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. + */ + /** + * x'0A' 代表 sqlite 中的 '\n' 字符。对于搜索结果中的标题和内容,我们会去掉 '\n' 和空格,以展示更多信息。 + */ + 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; + /** + * 定义搜索笔记的 SQL 查询语句,其中包括笔记的搜索投影和搜索条件。 + */ + 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(); + // 初始化 id + String id = null; + // 根据 Uri 的不同,执行不同的查询操作 + switch (mMatcher.match(uri)) { + // 查询所有笔记 + case URI_NOTE: + c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, + sortOrder); + break; + // 根据 id 查询笔记 + case URI_NOTE_ITEM: + // 获取 Uri 中的 id + id = uri.getPathSegments().get(1); + // 根据 id 查询笔记 + 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; + // 根据 id 查询数据 + case URI_DATA_ITEM: + // 获取 Uri 中的 id + id = uri.getPathSegments().get(1); + // 根据 id 查询数据 + c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs, null, null, sortOrder); + break; + // 查询笔记的搜索结果 + case URI_SEARCH: + case URI_SEARCH_SUGGEST: + // 如果查询中包含排序或者 projection,则抛出异常 + 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; + // 如果 Uri 不匹配,则抛出异常 + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + // 如果游标不为空,则设置游标的内容变化通知 Uri + if (c != null) { + c.setNotificationUri(getContext().getContentResolver(), uri); + } + return c; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + // 获取可写的 SQLiteDatabase 实例 + SQLiteDatabase db = mHelper.getWritableDatabase(); + // 定义变量用于存储插入后的数据行 ID + long dataId = 0, noteId = 0, insertedId = 0; + // 根据传入的 Uri 进行不同的插入操作 + switch (mMatcher.match(uri)) { + case URI_NOTE: + // 如果是插入 Note 数据表 + insertedId = noteId = db.insert(TABLE.NOTE, null, values); + break; + case URI_DATA: + // 如果是插入 Data 数据表 + if (values.containsKey(DataColumns.NOTE_ID)) { + // 获取 Note ID + noteId = values.getAsLong(DataColumns.NOTE_ID); + } else { + // 如果 ContentValues 中没有 Note ID,记录日志并退出方法 + Log.d(TAG, "Wrong data format without note id:" + values.toString()); + } + // 插入数据行 + insertedId = dataId = db.insert(TABLE.DATA, null, values); + break; + default: + // 如果传入的 Uri 不合法,抛出 IllegalArgumentException 异常 + throw new IllegalArgumentException("Unknown URI " + uri); + } + // 如果插入操作成功,通知相关 Uri 的观察者 + // 通知 Note Uri + if (noteId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null); + } + // 通知 Data Uri + if (dataId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); + } + // 返回新插入数据的 Uri + 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-case 语句匹配传入的 Uri + switch (mMatcher.match(uri)) { + // 如果是 URI_NOTE,表示删除笔记 + case URI_NOTE: + // 将选定条件和 "ID>0" 结合起来 + selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; + // 执行删除操作,并返回受影响的行数 + count = db.delete(TABLE.NOTE, selection, selectionArgs); + break; + // 如果是 URI_NOTE_ITEM,表示删除单个笔记 + case URI_NOTE_ITEM: + // 从 Uri 中获取笔记的 ID + id = uri.getPathSegments().get(1); + // 如果笔记 ID 小于等于 0,则不允许删除 + long noteId = Long.valueOf(id); + if (noteId <= 0) { + break; + } + // 执行删除操作,并返回受影响的行数 + count = db.delete(TABLE.NOTE, + NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); + break; + // 如果是 URI_DATA,表示删除数据 + case URI_DATA: + // 执行删除操作,并返回受影响的行数 + count = db.delete(TABLE.DATA, selection, selectionArgs); + deleteData = true; + break; + // 如果是 URI_DATA_ITEM,表示删除单个数据 + case URI_DATA_ITEM: + // 从 Uri 中获取数据的 ID + 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); + } + + // 如果受影响的行数大于 0 + if (count > 0) { + // 如果删除了数据,则通知数据发生了变化 + if (deleteData) { + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + // 通知 Uri 发生了变化 + 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; + + // 根据 Uri 进行分支处理 + switch (mMatcher.match(uri)) { + case URI_NOTE: + // 更新笔记版本号 + increaseNoteVersion(-1, selection, selectionArgs); + // 更新笔记数据 + count = db.update(TABLE.NOTE, values, selection, selectionArgs); + break; + case URI_NOTE_ITEM: + // 获取 Uri 中的 id + id = uri.getPathSegments().get(1); + // 更新笔记版本号 + increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); + // 根据 id 更新笔记数据 + 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: + // 获取 Uri 中的 id + id = uri.getPathSegments().get(1); + // 根据 id 更新数据表 + count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs); + updateData = true; + break; + default: + // 如果不匹配任何 Uri,抛出异常 + throw new IllegalArgumentException("Unknown URI " + uri); + } + + // 如果更新成功,发出通知 + if (count > 0) { + if (updateData) { + // 更新数据表时,通知笔记 Uri + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + // 通知当前 Uri + getContext().getContentResolver().notifyChange(uri, null); + } + return count; + } + + private String parseSelection(String selection) { + // 如果查询条件不为空,返回 AND (查询条件) + return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); + } + + private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { + // 构建 SQL 语句 + StringBuilder sql = new StringBuilder(120); + sql.append("UPDATE "); + sql.append(TABLE.NOTE); + sql.append(" SET "); + sql.append(NoteColumns.VERSION); + sql.append("=" + NoteColumns.VERSION + "+1 "); + + // 如果传入的 ID 或者查询条件不为空,则在 SQL 语句中添加 WHERE 子句 + if (id > 0 || !TextUtils.isEmpty(selection)) { + sql.append(" WHERE "); + } + // 如果传入的 ID 不为空,添加 ID 条件 + 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); + } + + // 执行 SQL 语句,增加笔记版本号 + mHelper.getWritableDatabase().execSQL(sql.toString()); + } + + @Override + public String getType(Uri uri) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/app/src/main/java/net/micode/notes/gtask/data/MetaData.java b/app/src/main/java/net/micode/notes/gtask/data/MetaData.java new file mode 100644 index 0000000..c60233d --- /dev/null +++ b/app/src/main/java/net/micode/notes/gtask/data/MetaData.java @@ -0,0 +1,103 @@ +/* + * 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; + +/** + + MetaData类是Task类的子类,表示GTask的元数据。 + */ +public class MetaData extends Task { + private final static String TAG = MetaData.class.getSimpleName(); + // 关联的gid + private String mRelatedGid = null; + /** + * 设置元数据的gid和相关信息 + * + * @param gid 元数据的gid + * @param metaInfo 元数据的相关信息 + */ + public void setMeta(String gid, JSONObject metaInfo) { + try { + // 将关联的gid放入JSONObject中 + metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); + } catch (JSONException e) { + Log.e(TAG, "failed to put related gid"); + } + // 将元数据的相关信息转换为字符串,设置为Task的notes + setNotes(metaInfo.toString()); + // 设置Task的名称为元数据的名称 + setName(GTaskStringUtils.META_NOTE_NAME); + } + + public String getRelatedGid() { + return mRelatedGid; + } + /** + * 判断元数据是否有值。 + * @return 如果有备注信息则返回true,否则返回false。 + */ + @Override + public boolean isWorthSaving() { + return getNotes() != null; + } + /** + * 通过远程JSON对象设置元数据内容。 + * @param js 远程JSON对象。 + */ + @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; + } + } + } + /** + * 本地JSON对象不应该调用该方法。 + * @param js 本地JSON对象。 + */ + @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"); + } +/*该方法接受一个 Cursor 参数,返回一个整型值。 +方法体中抛出了一个 IllegalAccessError 异常,并指定了异常消息为 "MetaData:getSyncAction should not be called",即 "MetaData:getSyncAction 不应该被调用"。*/ + @Override + public int getSyncAction(Cursor c) { + throw new IllegalAccessError("MetaData:getSyncAction should not be called"); + } + +} diff --git a/app/src/main/java/net/micode/notes/gtask/data/Node.java b/app/src/main/java/net/micode/notes/gtask/data/Node.java new file mode 100644 index 0000000..63950e0 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/data/SqlData.java b/app/src/main/java/net/micode/notes/gtask/data/SqlData.java new file mode 100644 index 0000000..d3ec3be --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java b/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java new file mode 100644 index 0000000..79a4095 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/data/Task.java b/app/src/main/java/net/micode/notes/gtask/data/Task.java new file mode 100644 index 0000000..6a19454 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/data/TaskList.java b/app/src/main/java/net/micode/notes/gtask/data/TaskList.java new file mode 100644 index 0000000..4ea21c5 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/exception/ActionFailureException.java b/app/src/main/java/net/micode/notes/gtask/exception/ActionFailureException.java new file mode 100644 index 0000000..15504be --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/exception/NetworkFailureException.java b/app/src/main/java/net/micode/notes/gtask/exception/NetworkFailureException.java new file mode 100644 index 0000000..b08cfb1 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java b/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java new file mode 100644 index 0000000..56c8e5e --- /dev/null +++ b/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java @@ -0,0 +1,124 @@ + +/* + * 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); + notification.contentIntent = 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/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java b/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java new file mode 100644 index 0000000..c67dfdf --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/remote/GTaskManager.java b/app/src/main/java/net/micode/notes/gtask/remote/GTaskManager.java new file mode 100644 index 0000000..d2b4082 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/gtask/remote/GTaskSyncService.java b/app/src/main/java/net/micode/notes/gtask/remote/GTaskSyncService.java new file mode 100644 index 0000000..cca36f7 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/model/Note.java b/app/src/main/java/net/micode/notes/model/Note.java new file mode 100644 index 0000000..6706cf6 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/model/WorkingNote.java b/app/src/main/java/net/micode/notes/model/WorkingNote.java new file mode 100644 index 0000000..be081e4 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/tool/BackupUtils.java b/app/src/main/java/net/micode/notes/tool/BackupUtils.java new file mode 100644 index 0000000..39f6ec4 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/tool/DataUtils.java b/app/src/main/java/net/micode/notes/tool/DataUtils.java new file mode 100644 index 0000000..2a14982 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/tool/GTaskStringUtils.java b/app/src/main/java/net/micode/notes/tool/GTaskStringUtils.java new file mode 100644 index 0000000..666b729 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/tool/ResourceParser.java b/app/src/main/java/net/micode/notes/tool/ResourceParser.java new file mode 100644 index 0000000..1ad3ad6 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java b/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java new file mode 100644 index 0000000..85723be --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java b/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java new file mode 100644 index 0000000..f221202 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java new file mode 100644 index 0000000..54e503b --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/DateTimePicker.java b/app/src/main/java/net/micode/notes/ui/DateTimePicker.java new file mode 100644 index 0000000..496b0cd --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java b/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java new file mode 100644 index 0000000..2c47ba4 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/DropdownMenu.java b/app/src/main/java/net/micode/notes/ui/DropdownMenu.java new file mode 100644 index 0000000..613dc74 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java b/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java new file mode 100644 index 0000000..96b77da --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java new file mode 100644 index 0000000..7e746a9 --- /dev/null +++ b/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -0,0 +1,879 @@ +/* + * 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(); + } + + + public void OnOpenMenu(View view) { + openOptionsMenu(); + } +} diff --git a/app/src/main/java/net/micode/notes/ui/NoteEditText.java b/app/src/main/java/net/micode/notes/ui/NoteEditText.java new file mode 100644 index 0000000..2afe2a8 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/NoteItemData.java b/app/src/main/java/net/micode/notes/ui/NoteItemData.java new file mode 100644 index 0000000..0f5a878 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/NotesListActivity.java b/app/src/main/java/net/micode/notes/ui/NotesListActivity.java new file mode 100644 index 0000000..c12fe24 --- /dev/null +++ b/app/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -0,0 +1,1017 @@ +/* + * 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 int mode = -1; + 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 Button mMenuSet; + + 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); + getWindow().setBackgroundDrawableResource(R.drawable.background1); + 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()); + mMenuSet = (Button) findViewById(R.id.btn_set); + 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 Menu menu; + private MenuItem mMoveMenu; + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + getMenuInflater().inflate(R.menu.note_list_options, menu); + this.menu = 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); + mMenuSet.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.clearChoices(); + mNotesListView.setItemChecked(0,true); + mNotesListView.setItemChecked(0,false); + + mNotesListView.setLongClickable(true); + System.out.println("-----------------onDestroyActionMode------------------"); + mNotesListAdapter.notifyDataSetChanged(); +// closeOptionsMenu(); +// mNotesListView.invalidate(); + mAddNewNote.setVisibility(View.VISIBLE); + mMenuSet.setVisibility(View.VISIBLE); + + + +// mNotesListView.setChoiceMode(ListView.CHOICE_MODE_NONE); + +// menu.clear(); +// menu.close(); + } + + + + public void finishActionMode() { + mActionMode.finish(); + mActionMode = null; + mNotesListAdapter.setChoiceMode(false); + mNotesListView.setLongClickable(true); + } + + + + 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); + mMenuSet.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() { + + System.out.println("-------onBackPressed---00000"); + 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); + mMenuSet.setVisibility(View.VISIBLE); + mTitleBar.setVisibility(View.GONE); + startAsyncNotesListQuery(); + break; + case NOTE_LIST: + System.out.println("-------onBackPressed---"); + 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); + } + //当是当前背景图片时,该按键隐藏 + if (mode == 1){ + menu.findItem(R.id.menu_background1).setVisible(false); + }else if (mode == 0){ + menu.findItem(R.id.menu_background2).setVisible(false); + }else if (mode == -1){ + menu.findItem(R.id.menu_background3).setVisible(false); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_background1:{ + mode = 1; + getWindow().setBackgroundDrawableResource(R.drawable.background1); + break; + } + case R.id.menu_background2:{ + mode = 0; + getWindow().setBackgroundDrawableResource(R.drawable.background2); + break; + } + case R.id.menu_background3:{ + mode = -1; + getWindow().setBackgroundDrawableResource(R.drawable.background3); + break; + } + 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; + } + + public void OnOpenMenu(View view) { + openOptionsMenu(); + } +} diff --git a/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java b/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java new file mode 100644 index 0000000..51c9cb9 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/NotesListItem.java b/app/src/main/java/net/micode/notes/ui/NotesListItem.java new file mode 100644 index 0000000..1221e80 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java b/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java new file mode 100644 index 0000000..07c5f7e --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider.java b/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider.java new file mode 100644 index 0000000..ec6f819 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_2x.java b/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_2x.java new file mode 100644 index 0000000..adcb2f7 --- /dev/null +++ b/app/src/main/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/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_4x.java b/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_4x.java new file mode 100644 index 0000000..c12a02e --- /dev/null +++ b/app/src/main/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/app/src/main/res/color/primary_text_dark.xml b/app/src/main/res/color/primary_text_dark.xml new file mode 100644 index 0000000..8ad98e3 --- /dev/null +++ b/app/src/main/res/color/primary_text_dark.xml @@ -0,0 +1,22 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/secondary_text_dark.xml b/app/src/main/res/color/secondary_text_dark.xml new file mode 100644 index 0000000..9cf8a1a --- /dev/null +++ b/app/src/main/res/color/secondary_text_dark.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/background1.png b/app/src/main/res/drawable-hdpi/background1.png new file mode 100644 index 0000000000000000000000000000000000000000..a2ae72e0c64a4adea596ae011fd0cea129c9046b GIT binary patch literal 1825878 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 `Df9e?ZeF*U!%OArTN~`Z((bB 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%0Dx*iV)gvD#YqQ$mw;UZhRW}Qup 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ⅇ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