X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FBookmarksActivity.java;h=e4aa925829aa87ff08b00a8ba1f63be0b8b97168;hb=94b8eb7e3ab8d12885743607276df840832570f1;hp=4536001b1554b4f586ac7468f5600a8a9d879358;hpb=b9b9315f5b6b0bc171082f11660ca390748c0c2b;p=PrivacyBrowserAndroid.git diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java index 4536001b..e4aa9258 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java @@ -64,7 +64,7 @@ import java.io.ByteArrayOutputStream; public class BookmarksActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, EditBookmarkDialog.EditBookmarkListener, EditBookmarkFolderDialog.EditBookmarkFolderListener, MoveToFolderDialog.MoveToFolderListener { - // `bookmarksDatabaseHelper` is public static so it can be accessed from `EditBookmarkDialog` and `MoveToFolderDialog`. It is also used in `onCreate()`, + // `bookmarksDatabaseHelper` is public static so it can be accessed from `CreateBookmarkFolderDialog`, `EditBookmarkDialog`, `EditBookmarkFolderDialog` and `MoveToFolderDialog`. It is also used in `onCreate()`, // `onCreateBookmarkCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. public static BookmarksDatabaseHelper bookmarksDatabaseHelper; @@ -83,8 +83,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // `contextualActionMode` is used in `onCreate()` and `onEditBookmarkSave()`. private ActionMode contextualActionMode; - // `selectedBookmarkPosition` is used in `onCreate()` and `onEditBookmarkSave()`. - private int selectedBookmarkPosition; + // `bookmarkListViewPosition` is used in `onCreate()`, `onSaveEditBookmark()`, and `onSaveEditBookmarkFolder()`. + private int bookmarksListViewPosition; // `appBar` is used in `onCreate()` and `updateBookmarksListView()`. private ActionBar appBar; @@ -120,7 +120,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma appBar.setDisplayHomeAsUpEnabled(true); - // Initialize the database handler and the `ListView`. `this` specifies the context. The two `nulls` do not specify the database name or a `CursorFactory`. + // Initialize the database helper and the `ListView`. `this` specifies the context. The two `nulls` do not specify the database name or a `CursorFactory`. // The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`. bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this, null, null, 0); bookmarksListView = (ListView) findViewById(R.id.bookmarks_listview); @@ -296,16 +296,17 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Instantiate the common variables. int numberOfBookmarks; + int selectedBookmarkPosition; int selectedBookmarkNewPosition; - SparseBooleanArray bookmarkPositionSparseBooleanArray; + final SparseBooleanArray selectedBookmarksPositionsSparseBooleanArray; switch (menuItemId) { case R.id.move_bookmark_up: // Get the array of checked bookmarks. - bookmarkPositionSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); + selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); // Store the position of the selected bookmark. - selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(0); + selectedBookmarkPosition = selectedBookmarksPositionsSparseBooleanArray.keyAt(0); // Initialize `selectedBookmarkNewPosition`. selectedBookmarkNewPosition = 0; @@ -318,18 +319,18 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Update the display order for the current bookmark. if (i == selectedBookmarkPosition) { // The current bookmark is the selected bookmark. // Move the current bookmark up one. - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(currentBookmarkDatabaseId, i - 1); + bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i - 1); selectedBookmarkNewPosition = i - 1; } else if ((i + 1) == selectedBookmarkPosition){ // The current bookmark is immediately above the selected bookmark. // Move the current bookmark down one. - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(currentBookmarkDatabaseId, i + 1); + bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i + 1); } else { // The current bookmark is not changing positions. // Move `bookmarksCursor` to the current bookmark position. bookmarksCursor.moveToPosition(i); // Update the display order only if it is not correct in the database. if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER)) != i) { - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(currentBookmarkDatabaseId, i); + bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i); } } } @@ -347,10 +348,10 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma case R.id.move_bookmark_down: // Get the array of checked bookmarks. - bookmarkPositionSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); + selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); // Store the position of the selected bookmark. - selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(0); + selectedBookmarkPosition = selectedBookmarksPositionsSparseBooleanArray.keyAt(0); // Initialize `selectedBookmarkNewPosition`. selectedBookmarkNewPosition = 0; @@ -363,18 +364,18 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Update the display order for the current bookmark. if (i == selectedBookmarkPosition) { // The current bookmark is the selected bookmark. // Move the current bookmark down one. - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(currentBookmarkDatabaseId, i + 1); + bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i + 1); selectedBookmarkNewPosition = i + 1; } else if ((i - 1) == selectedBookmarkPosition) { // The current bookmark is immediately below the selected bookmark. // Move the bookmark below the selected bookmark up one. - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(currentBookmarkDatabaseId, i - 1); + bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i - 1); } else { // The current bookmark is not changing positions. // Move `bookmarksCursor` to the current bookmark position. bookmarksCursor.moveToPosition(i); // Update the display order only if it is not correct in the database. if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER)) != i) { - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(currentBookmarkDatabaseId, i); + bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i); } } } @@ -399,11 +400,14 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma break; case R.id.edit_bookmark: + // Store the scroll position of the bookmarks `ListView`. + bookmarksListViewPosition = bookmarksListView.getFirstVisiblePosition(); + // Get the array of checked bookmarks. - bookmarkPositionSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); + selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); - // Store the position of the selected bookmark. - selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(0); + // Get the position of the selected bookmark. + selectedBookmarkPosition = selectedBookmarksPositionsSparseBooleanArray.keyAt(0); // Move to the selected database ID and find out if it is a folder. bookmarksCursor.moveToPosition(selectedBookmarkPosition); @@ -427,28 +431,32 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma break; case R.id.delete_bookmark: - // Get an array of the selected rows. - final long[] selectedBookmarksLongArray = bookmarksListView.getCheckedItemIds(); + // Get an array of the selected rows IDs. + final long[] selectedBookmarksIdsLongArray = bookmarksListView.getCheckedItemIds(); - // Get the array of checked bookmarks. - bookmarkPositionSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); + // Get the array of checked bookmarks. `.clone()` makes a copy that won't change if `bookmarksListView` is reloaded, which is needed for re-selecting the bookmarks on undelete. + selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.getCheckedItemPositions().clone(); + + // Store the current scroll position for the purpose of restoring it on undelete. + final int scrollPositionBeforeDelete = bookmarksListView.getFirstVisiblePosition(); - // Store the position of the first selected bookmark. - selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(0); + // Store the scroll position of the bookmarks `ListView`. + bookmarksListViewPosition = bookmarksListView.getFirstVisiblePosition(); - updateBookmarksListViewExcept(selectedBookmarksLongArray, currentFolder); + // Display the bookmarks except for those that are going to be deleted. + updateBookmarksListViewExcept(selectedBookmarksIdsLongArray, currentFolder); - // Scroll to where the first deleted bookmark was located. - bookmarksListView.setSelection(selectedBookmarkPosition - 5); + // Restore the scroll position. + bookmarksListView.setSelection(bookmarksListViewPosition); // Create `snackbarMessage`. String snackbarMessage; // Determine how many items are in the array and prepare an appropriate Snackbar message. - if (selectedBookmarksLongArray.length == 1) { + if (selectedBookmarksIdsLongArray.length == 1) { snackbarMessage = getString(R.string.one_bookmark_deleted); } else { - snackbarMessage = selectedBookmarksLongArray.length + " " + getString(R.string.bookmarks_deleted); + snackbarMessage = selectedBookmarksIdsLongArray.length + " " + getString(R.string.bookmarks_deleted); } // Show a SnackBar. @@ -468,14 +476,19 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Refresh the ListView to show the rows again. updateBookmarksListView(currentFolder); - // Scroll to where the first deleted bookmark was located. - bookmarksListView.setSelection(selectedBookmarkPosition - 5); + // Select the previously selected bookmarks. + for (int i = 0; i < selectedBookmarksPositionsSparseBooleanArray.size(); i++) { + bookmarksListView.setItemChecked(selectedBookmarksPositionsSparseBooleanArray.keyAt(i), true); + } + + // Restore the scroll position. + bookmarksListView.setSelection(scrollPositionBeforeDelete); break; // The `Snackbar` was dismissed without the `Undo` button being pushed. default: // Delete each selected row. - for (long databaseIdLong : selectedBookmarksLongArray) { + for (long databaseIdLong : selectedBookmarksIdsLongArray) { // Convert `databaseIdLong` to an int. int databaseIdInt = (int) databaseIdLong; @@ -497,7 +510,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Update the display order only if it is not correct in the database. if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER)) != i) { - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(currentBookmarkDatabaseId, i); + bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i); } } break; @@ -528,9 +541,22 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } }); - // Set a FloatingActionButton for creating new bookmarks. - FloatingActionButton createBookmarkFAB = (FloatingActionButton) findViewById(R.id.create_bookmark_fab); - createBookmarkFAB.setOnClickListener(new View.OnClickListener() { + // Get handles for the `FloatingActionButtons. + FloatingActionButton createBookmarkFolderFab = (FloatingActionButton) findViewById(R.id.create_bookmark_folder_fab); + FloatingActionButton createBookmarkFab = (FloatingActionButton) findViewById(R.id.create_bookmark_fab); + + // Set the create new bookmark folder FAB to display the dialog box. + createBookmarkFolderFab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Show the `CreateBookmarkFolderDialog` `AlertDialog` and name the instance `@string/create_folder`. + AppCompatDialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog(); + createBookmarkFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_folder)); + } + }); + + // Set the create new bookmark FAB to display the dialog box. + createBookmarkFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Show the `CreateBookmarkDialog` `AlertDialog` and name the instance `@string/create_bookmark`. @@ -567,12 +593,6 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } break; - case R.id.create_folder: - // Show the `CreateBookmarkFolderDialog` `AlertDialog` and name the instance `@string/create_folder`. - AppCompatDialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog(); - createBookmarkFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_folder)); - break; - case R.id.options_menu_select_all_bookmarks: int numberOfBookmarks = bookmarksListView.getCount(); @@ -657,7 +677,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Move all the bookmarks down one in the display order. for (int i = 0; i < bookmarksListView.getCount(); i++) { int databaseId = (int) bookmarksListView.getItemIdAtPosition(i); - bookmarksDatabaseHelper.updateBookmarkDisplayOrder(databaseId, i + 1); + bookmarksDatabaseHelper.updateDisplayOrder(databaseId, i + 1); } // Create the folder, placing it at the top of the ListView @@ -696,9 +716,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Close the contextual action mode. contextualActionMode.finish(); - // Refresh the `ListView`. `setSelection` scrolls to the position of the bookmark that was edited. + // Refresh the `ListView`. `setSelection` scrolls to the previous `ListView` position. updateBookmarksListView(currentFolder); - bookmarksListView.setSelection(selectedBookmarkPosition); + bookmarksListView.setSelection(bookmarksListViewPosition); } @Override @@ -707,58 +727,64 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma EditText editFolderNameEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.edit_folder_name_edittext); String newFolderNameString = editFolderNameEditText.getText().toString(); - // Check to see if the new folder name is unique. - Cursor bookmarkFolderCursor = bookmarksDatabaseHelper.getFolderCursor(newFolderNameString); - int existingFoldersWithNewName = bookmarkFolderCursor.getCount(); - bookmarkFolderCursor.close(); - if ( ((existingFoldersWithNewName == 0) || newFolderNameString.equals(oldFolderNameString)) && !newFolderNameString.isEmpty()) { - // Get a long array with the the database ID of the selected folder and convert it to an `int`. - long[] selectedFolderLongArray = bookmarksListView.getCheckedItemIds(); - int selectedFolderDatabaseId = (int) selectedFolderLongArray[0]; - - // Get the `RadioButtons` from the `Dialog`. - RadioButton currentFolderIconRadioButton = (RadioButton) dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton); - RadioButton defaultFolderIconRadioButton = (RadioButton) dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton); - - // Check if the favorite icon has changed. - if (currentFolderIconRadioButton.isChecked()) { - // Update the folder name if it has changed without modifying the favorite icon. - if (!newFolderNameString.equals(oldFolderNameString)) { - bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString); - - // Refresh the `ListView`. `setSelection` scrolls to the position of the folder that was edited. - updateBookmarksListView(currentFolder); - bookmarksListView.setSelection(selectedBookmarkPosition); - } - } else { // Update the folder icon. - // Get the new folder icon `Bitmap`. - Bitmap folderIconBitmap; - if (defaultFolderIconRadioButton.isChecked()) { - // Get the default folder icon `ImageView` from the `Drawable` and convert it to a `Bitmap`. - ImageView folderIconImageView = (ImageView) dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon); - Drawable folderIconDrawable = folderIconImageView.getDrawable(); - BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable; - folderIconBitmap = folderIconBitmapDrawable.getBitmap(); - } else { // Get the web page icon `ImageView` from the `Dialog`. - folderIconBitmap = MainWebViewActivity.favoriteIconBitmap; - } + // Get a long array with the the database ID of the selected folder and convert it to an `int`. + long[] selectedFolderLongArray = bookmarksListView.getCheckedItemIds(); + int selectedFolderDatabaseId = (int) selectedFolderLongArray[0]; + + // Get the `RadioButtons` from the `Dialog`. + RadioButton currentFolderIconRadioButton = (RadioButton) dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton); + RadioButton defaultFolderIconRadioButton = (RadioButton) dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton); + + // Check if the favorite icon has changed. + if (currentFolderIconRadioButton.isChecked()) { // Only the name has changed. + // Update the name in the database. + bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString); + } else if (!currentFolderIconRadioButton.isChecked() && newFolderNameString.equals(oldFolderNameString)) { // Only the icon has changed. + // Get the new folder icon `Bitmap`. + Bitmap folderIconBitmap; + if (defaultFolderIconRadioButton.isChecked()) { + // Get the default folder icon `ImageView` from the `Drawable` and convert it to a `Bitmap`. + ImageView folderIconImageView = (ImageView) dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon); + Drawable folderIconDrawable = folderIconImageView.getDrawable(); + BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable; + folderIconBitmap = folderIconBitmapDrawable.getBitmap(); + } else { // Get the web page icon `ImageView` from the `Dialog`. + folderIconBitmap = MainWebViewActivity.favoriteIconBitmap; + } - // Convert the folder `Bitmap` to a byte array. `0` is for lossless compression (the only option for a PNG). - ByteArrayOutputStream folderIconByteArrayOutputStream = new ByteArrayOutputStream(); - folderIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, folderIconByteArrayOutputStream); - byte[] folderIconByteArray = folderIconByteArrayOutputStream.toByteArray(); + // Convert the folder `Bitmap` to a byte array. `0` is for lossless compression (the only option for a PNG). + ByteArrayOutputStream folderIconByteArrayOutputStream = new ByteArrayOutputStream(); + folderIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, folderIconByteArrayOutputStream); + byte[] folderIconByteArray = folderIconByteArrayOutputStream.toByteArray(); + + // Update the folder icon in the database. + bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, folderIconByteArray); + } else { // The folder icon and the name have changed. + // Get the new folder icon `Bitmap`. + Bitmap folderIconBitmap; + if (defaultFolderIconRadioButton.isChecked()) { + // Get the default folder icon `ImageView` from the `Drawable` and convert it to a `Bitmap`. + ImageView folderIconImageView = (ImageView) dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon); + Drawable folderIconDrawable = folderIconImageView.getDrawable(); + BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable; + folderIconBitmap = folderIconBitmapDrawable.getBitmap(); + } else { // Get the web page icon `ImageView` from the `Dialog`. + folderIconBitmap = MainWebViewActivity.favoriteIconBitmap; + } - bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString, folderIconByteArray); + // Convert the folder `Bitmap` to a byte array. `0` is for lossless compression (the only option for a PNG). + ByteArrayOutputStream folderIconByteArrayOutputStream = new ByteArrayOutputStream(); + folderIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, folderIconByteArrayOutputStream); + byte[] folderIconByteArray = folderIconByteArrayOutputStream.toByteArray(); - // Refresh the `ListView`. `setSelection` scrolls to the position of the folder that was edited. - updateBookmarksListView(currentFolder); - bookmarksListView.setSelection(selectedBookmarkPosition); - } - } else { // Don't edit the folder because the new name is not unique. - String cannot_rename_folder = getResources().getString(R.string.cannot_save_folder) + " \"" + newFolderNameString + "\""; - Snackbar.make(findViewById(R.id.bookmarks_coordinatorlayout), cannot_rename_folder, Snackbar.LENGTH_INDEFINITE).show(); + // Update the folder name and icon in the database. + bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString, folderIconByteArray); } + // Refresh the `ListView`. `setSelection` scrolls to the previous `ListView` position. + updateBookmarksListView(currentFolder); + bookmarksListView.setSelection(bookmarksListViewPosition); + // Close the contextual action mode. contextualActionMode.finish(); }