From 5bfd09dfd0ad8aa6d758df0b11c56060555b394d Mon Sep 17 00:00:00 2001 From: zkx Date: Wed, 3 Jan 2024 23:21:28 +0800 Subject: [PATCH] add: 1. delete folder will move notes in it and itself to the trash 2. clear notes in trash --- .../micode/notes/ui/NotesListActivity.java | 131 +++++++++++++----- src/main/res/menu/trash_folder.xml | 24 ++++ src/main/res/values-zh-rCN/strings.xml | 11 +- src/main/res/values-zh-rTW/strings.xml | 11 +- src/main/res/values/strings.xml | 5 + 5 files changed, 144 insertions(+), 38 deletions(-) create mode 100644 src/main/res/menu/trash_folder.xml diff --git a/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/main/java/net/micode/notes/ui/NotesListActivity.java index 5b452d5..f9b2164 100644 --- a/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -16,6 +16,7 @@ package net.micode.notes.ui; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -92,8 +93,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; private enum ListEditState { - NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER - }; //NOTE: 三种编辑状态@zhoukexing 2024/1/2 19:31 + NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER, TRASH_FOLDER + }; //NOTE: 三种编辑状态@zhoukexing 2024/1/2 19:31 新增一个 private ListEditState mState; @@ -135,6 +136,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private final static int REQUEST_CODE_OPEN_NODE = 102; private final static int REQUEST_CODE_NEW_NODE = 103; + private String mTitle; + private String mMessage; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -321,11 +325,26 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt int itemId = item.getItemId(); if (itemId == R.id.delete) { + switch (mState) { + case SUB_FOLDER: + case CALL_RECORD_FOLDER: + case NOTE_LIST: + mTitle = getString(R.string.alert_title_delete); + mMessage = getString(R.string.alert_message_delete_notes, + mNotesListAdapter.getSelectedCount()); + break; + case TRASH_FOLDER: + mTitle = getString(R.string.alert_title_delete_true); + mMessage = getString(R.string.alert_message_delete_notes_true, + mNotesListAdapter.getSelectedCount()); + break; + default: + break; + } AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); - builder.setTitle(getString(R.string.alert_title_delete)); + builder.setTitle(mTitle); builder.setIcon(android.R.drawable.ic_dialog_alert); - builder.setMessage(getString(R.string.alert_message_delete_notes, - mNotesListAdapter.getSelectedCount())); + builder.setMessage(mMessage); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, @@ -357,7 +376,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt /** * Minus TitleBar's height */ - if (mState == ListEditState.SUB_FOLDER) { + if (mState == ListEditState.SUB_FOLDER | + mState == ListEditState.TRASH_FOLDER) { + // 回收站的ui显示 @zkx eventY -= mTitleBar.getHeight(); start -= mTitleBar.getHeight(); } @@ -473,34 +494,34 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); } + /** + * @method: batchDelete + * @description: 删除若干个选中的便签。 + * 根据NotesListAdapter里的mSelectedIndex数据成员里的标记,为真表示选中,予以删除。 + * @date: 2024/1/3 23:02 + * @author: zhoukexing + * @param: [] + * @return: void + */ private void batchDelete() { new AsyncTask>() { + @SuppressLint("StaticFieldLeak") protected HashSet doInBackground(Void... unused) { HashSet widgets = mNotesListAdapter.getSelectedWidget(); -// if (!isSyncMode()) { //在AS的虚拟机里,不能联网,不在同步模式下 -// // if not synced, delete notes directly -// if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter -// .getSelectedItemIds())) { -// } else { -// Log.e(TAG, "Delete notes error, should not happens"); -// } -// } else { - if (mCurrentFolderId == Notes.ID_TRASH_FOLER){ - // if in trash, really delete notes - if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter - .getSelectedItemIds())) { - } else { - Log.e(TAG, "Delete notes error, should not happens"); - } + if (mCurrentFolderId == Notes.ID_TRASH_FOLER){ + // if in trash, really delete notes + if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter + .getSelectedItemIds())) { } else { - // move notes to trash - if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter - .getSelectedItemIds(), Notes.ID_TRASH_FOLER)) { - Log.e(TAG, "Move notes to trash folder error, should not happens"); - } + Log.e(TAG, "Delete notes error, should not happens"); } - -// } + } else { + // move notes to trash + if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter + .getSelectedItemIds(), Notes.ID_TRASH_FOLER)) { + Log.e(TAG, "Move notes to trash folder error, should not happens"); + } + } return widgets; } @@ -508,8 +529,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt protected void onPostExecute(HashSet widgets) { if (widgets != null) { for (AppWidgetAttribute widget : widgets) { + // widget挂件的Id和Type都不是非法的《==》存在这个widget挂件 @zkx if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID && widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) { + // ==》 删除这个挂件 updateWidget(widget.widgetId, widget.widgetType); } } @@ -538,11 +561,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt // 所有与要删除文件夹相关的 widgets HashSet widgets = DataUtils.getFolderNoteWidget(mContentResolver, folderId); - if (!isSyncMode()) { - // if not synced, delete folder directly + if (mCurrentFolderId == Notes.ID_TRASH_FOLER) { + // if in trash, delete folder directly DataUtils.batchDeleteNotes(mContentResolver, ids); } else { - // in sync mode, we'll move the deleted folder into the trash folder + // move the deleted folder into the trash folder DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_TRASH_FOLER); } // 更新 widgets @@ -726,7 +749,13 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt // 特殊情况:子文件夹是“回收站”,要显式地说明展示底部栏(模仿下面的call_record_folder) @zkx // 添加mAddNewNote.setVisibility(View.VISIBLE);此行后, // sub_folder 和 call_record_folder 两种情况无差别,无需分开处理 + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mState = ListEditState.NOTE_LIST; + mTitleBar.setVisibility(View.GONE); + startAsyncNotesListQuery(); + break; case CALL_RECORD_FOLDER: + case TRASH_FOLDER: mCurrentFolderId = Notes.ID_ROOT_FOLDER; mState = ListEditState.NOTE_LIST; mAddNewNote.setVisibility(View.VISIBLE); @@ -840,6 +869,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt 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.TRASH_FOLDER) { + getMenuInflater().inflate(R.menu.trash_folder, menu); } else if (mState == ListEditState.CALL_RECORD_FOLDER) { getMenuInflater().inflate(R.menu.call_record_folder, menu); } else { @@ -881,10 +912,45 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt onSearchRequested(); } else if (itemId == R.id.menu_trash) { openTrashFolder(); + } else if (itemId == R.id.menu_empty_trash) { + emptyTrashFolder(); } return true; } + /** + * @method: emptyTrashFolder + * @description: 通过“选中”回收站下所有便签,清空整个回收站 + * @date: 2024/1/3 22:59 + * @author: zhoukexing + * @param: [] + * @return: void + */ + private void emptyTrashFolder() { + // 利用已有函数,在数据结构上“选中”所有便签 @zkx + mNotesListAdapter.selectAll(true); + // 模仿选中R.id.delete,构建对话框 + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle(getString(R.string.alert_title_delete_true)); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getString(R.string.alert_message_delete_notes_true, + mNotesListAdapter.getMNotesCount())); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + // 这里体现了【层次化/模块化】的软件哲学。 + // 当时实现这个功能有两条路可以走, + // 一条是:修改已有batchDelete里的select函数,改为选中所有,实现一个alldelete函数 + // 一条是:利用batchDelete的功能(删除选中的便签),在进入batchDelete前选中所有 + // 后者是更好的。前者需要修改方法,是侵入式的,而且会造成许多代码的重复,没有做到方法与方法之间的低耦合。 + batchDelete(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + } + /** * @method: openTrashFolder * @description: 打开回收站 todo:添加30天后自动删除【时间】 @@ -897,7 +963,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mCurrentFolderId = Notes.ID_TRASH_FOLER; startAsyncNotesListQuery(); // 正常打开文件夹 - mState = ListEditState.SUB_FOLDER; + mState = ListEditState.TRASH_FOLDER; // 将顶部栏设置为 data.getSnippet 文件夹名称 mTitleBar.setText(NotesListActivity.this .getString(R.string.menu_trash)); @@ -1012,6 +1078,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt break; case SUB_FOLDER: case CALL_RECORD_FOLDER: + case TRASH_FOLDER: if (item.getType() == Notes.TYPE_NOTE) { openNode(item); } else { diff --git a/src/main/res/menu/trash_folder.xml b/src/main/res/menu/trash_folder.xml new file mode 100644 index 0000000..6e414c2 --- /dev/null +++ b/src/main/res/menu/trash_folder.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 111cb05..9ab5022 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -44,6 +44,7 @@ 搜索 回收站 删除 + 清空回收站 移动到文件夹 选中了 %d 项 没有选中项,操作无效 @@ -68,9 +69,13 @@ 上一级文件夹 已添加到桌面 删除 - 确认要删除所选的 %d 条便签吗? - 确认要删除该条便签吗? - 确认删除文件夹及所包含的便签吗? + 确认要删除所选的 %d 条便签吗?(将在回收站保存30天) + 确认要删除该条便签吗?(将在回收站保存30天) + 确认删除文件夹及所包含的便签吗?(将在回收站保存30天) + 确认删除文件夹及所包含的便签吗? + 删除 + 确认要删除所选的 %d 条便签吗? + 确认要删除该条便签吗? 已将所选 %1$d 条便签移到 %2$s 文件夹 SD卡被占用,不能操作 diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml index 01b6815..05133ea 100644 --- a/src/main/res/values-zh-rTW/strings.xml +++ b/src/main/res/values-zh-rTW/strings.xml @@ -35,6 +35,10 @@ 發送郵件 浏覽網頁 打開地圖 + 確認刪除檔夾及所包含的便簽嗎? + 删除 + 确认要刪除所選的 %d 條便籤嗎? + 确认要删除該條便籤嗎? 已將所選 %1$d 便籤移到 %2$s 文件夾 新建文件夾 @@ -45,6 +49,7 @@ 搜尋 回收站 刪除 + 清空回收站 移動到文件夾 選中了 %d 項 沒有選中項,操作無效 @@ -69,9 +74,9 @@ 上一級文件夾 已添加到桌面 刪除 - 确认要刪除所選的 %d 條便籤嗎? - 确认要删除該條便籤嗎? - 確認刪除檔夾及所包含的便簽嗎? + 确认要删除所选的 %d 条便签吗?(将在回收站保存30天) + 确认要删除该条便签吗?(将在回收站保存30天) + 确认删除文件夹及所包含的便签吗?(将在回收站保存30天) SD卡被佔用,不能操作 導出TXT時發生錯誤,請檢查SD卡 要查看的便籤不存在 diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index c1831b0..c71187b 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -48,6 +48,7 @@ Search Trash Folder Delete + Empty Trash Move to folder %d selected Nothing selected, the operation is invalid @@ -75,6 +76,10 @@ Delete selected notes Confirm to delete the selected %d notes? Confirm to delete this note? + Confirm to delete folder and its notes? + Delete selected notes + Confirm to delete the selected %d notes? + Confirm to delete this note? Have moved selected %1$d notes to %2$s folder SD card busy, not available now