X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2FBookmarksActivity.java;h=65d1cfddb7e9110b515bc4786fc4e9d7b90c40d7;hp=ca004072a54ac11c68d78991849687a2e591b4c5;hb=0abf9642763f1af98af73b2fc3cc44752a342db3;hpb=c4ad9f457f41cbc86391e0099629cd94a235258a diff --git a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java index ca004072..65d1cfdd 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java @@ -24,7 +24,6 @@ import android.app.DialogFragment; import android.content.Context; import android.content.Intent; import android.database.Cursor; -import android.database.DatabaseUtils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Typeface; @@ -34,8 +33,6 @@ import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.app.NavUtils; -import android.support.v4.content.ContextCompat; -import android.support.v4.widget.CursorAdapter; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; @@ -47,7 +44,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; -import android.widget.CheckBox; +import android.widget.CursorAdapter; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; @@ -58,22 +55,28 @@ import java.io.ByteArrayOutputStream; public class BookmarksActivity extends AppCompatActivity implements CreateBookmark.CreateBookmarkListener, CreateBookmarkFolder.CreateBookmarkFolderListener, EditBookmark.EditBookmarkListener, - EditBookmarkFolder.EditBookmarkFolderListener { - // `bookmarksDatabaseHandler` is public static so it can be accessed from EditBookmark. It is also used in `onCreate()`, + EditBookmarkFolder.EditBookmarkFolderListener, MoveToFolder.MoveToFolderListener { + + // `bookmarksDatabaseHandler` is public static so it can be accessed from `EditBookmark` and `MoveToFolder`. It is also used in `onCreate()`, // `onCreateBookmarkCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. public static BookmarksDatabaseHandler bookmarksDatabaseHandler; - // `bookmarksListView` is public static so it can be accessed from EditBookmark. - // It is also used in `onCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. - public static ListView bookmarksListView; + // `currentFolder` is public static so it can be accessed from `MoveToFolder`. + // It is used in `onCreate`, `onOptionsItemSelected()`, `onCreateBookmarkCreate`, `onCreateBookmarkFolderCreate`, and `onEditBookmarkSave`. + public static String currentFolder; + + // `checkedItemIds` is public static so it can be accessed from `EditBookmark`, `EditBookmarkFolder`, and `MoveToFolder`. + // It is also used in `onActionItemClicked`. + public static long[] checkedItemIds; - // `currentFolder` is used in `onCreate`, `onOptionsItemSelected()`, `onCreateBookmarkCreate`, `onCreateBookmarkFolderCreate`, and `onEditBookmarkSave`. - private String currentFolder; + + // `bookmarksListView` is used in `onCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. + private ListView bookmarksListView; // `contextualActionMode` is used in `onCreate()` and `onEditBookmarkSave()`. private ActionMode contextualActionMode; - // `selectedBookmarkPosition` is used in `onCreate()` and `onEditBookarkSave()`. + // `selectedBookmarkPosition` is used in `onCreate()` and `onEditBookmarkSave()`. private int selectedBookmarkPosition; // `appBar` is used in `onCreate()` and `updateBookmarksListView()`. @@ -133,11 +136,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Reload the ListView with `currentFolder`. updateBookmarksListView(currentFolder); } else { // Load the URL into `mainWebView`. - // Get the bookmark URL and assign it to formattedUrlString. + // Get the bookmark URL and assign it to formattedUrlString. `mainWebView` will automatically reload when `BookmarksActivity` closes. MainWebViewActivity.formattedUrlString = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_URL)); - // Load formattedUrlString and return to the main activity. - MainWebViewActivity.mainWebView.loadUrl(MainWebViewActivity.formattedUrlString); NavUtils.navigateUpFromSameTask(bookmarksActivity); } @@ -179,6 +180,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma editBookmarkMenuItem = menu.findItem(R.id.edit_bookmark); selectAllBookmarksMenuItem = menu.findItem(R.id.context_menu_select_all_bookmarks); + // Get a handle for `contextualActionMode` so we can close it programatically. + contextualActionMode = mode; + return true; } @@ -195,6 +199,11 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Calculate the number of selected bookmarks. int numberOfSelectedBookmarks = selectedBookmarksLongArray.length; + // Sometimes Android forgets to close the contextual app bar when all the items are deselected. + if (numberOfSelectedBookmarks == 0) { + mode.finish(); + } + // List the number of selected bookmarks in the subtitle. mode.setSubtitle(numberOfSelectedBookmarks + " " + getString(R.string.selected)); @@ -331,18 +340,31 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma bookmarksListView.setSelection(selectedBookmarkNewPosition - 5); break; - case R.id.edit_bookmark: - // Get a handle for `contextualActionMode` so we can close it when `editBookmarkDialog` is finished. - contextualActionMode = mode; + case R.id.move_to_folder: + // Store `checkedItemIds` for use by the `AlertDialog`. + checkedItemIds = bookmarksListView.getCheckedItemIds(); + // Show the `MoveToFolder` `AlertDialog` and name the instance `@string/move_to_folder + DialogFragment moveToFolderDialog = new MoveToFolder(); + moveToFolderDialog.show(getFragmentManager(), getResources().getString(R.string.move_to_folder)); + break; + + case R.id.edit_bookmark: // Get a handle for `selectedBookmarkPosition` so we can scroll to it after refreshing the ListView. bookmarkPositionSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); - selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(0); + for (int i = 0; i < bookmarkPositionSparseBooleanArray.size(); i++) { + // Find the bookmark that is selected and save the position to `selectedBookmarkPosition`. + if (bookmarkPositionSparseBooleanArray.valueAt(i)) + selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(i); + } // Move to the selected database ID and find out if it is a folder. bookmarksCursor.moveToPosition(selectedBookmarkPosition); boolean isFolder = (bookmarksCursor.getInt(bookmarksCursor.getColumnIndex(BookmarksDatabaseHandler.IS_FOLDER)) == 1); + // Store `checkedItemIds` for use by the `AlertDialog`. + checkedItemIds = bookmarksListView.getCheckedItemIds(); + if (isFolder) { // Save the current folder name. oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_NAME)); @@ -363,12 +385,16 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Get a handle for `selectedBookmarkPosition` so we can scroll to it after refreshing the ListView. bookmarkPositionSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); - selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(0); + for (int i = 0; i < bookmarkPositionSparseBooleanArray.size(); i++) { + // Find the bookmark that is selected and save the position to `selectedBookmarkPosition`. + if (bookmarkPositionSparseBooleanArray.valueAt(i)) + selectedBookmarkPosition = bookmarkPositionSparseBooleanArray.keyAt(i); + } updateBookmarksListViewExcept(selectedBookmarksLongArray, currentFolder); // Scroll to where the deleted bookmark was located. - bookmarksListView.setSelection(selectedBookmarkPosition); + bookmarksListView.setSelection(selectedBookmarkPosition - 5); String snackbarMessage; @@ -390,14 +416,30 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma .setCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { + // Android Studio wants to see entries for every possible `Snackbar.Callback` even if they aren't used. switch (event) { // The user pushed the "Undo" button. case Snackbar.Callback.DISMISS_EVENT_ACTION: // Refresh the ListView to show the rows again. updateBookmarksListView(currentFolder); + // Scroll to where the deleted bookmark was located. + bookmarksListView.setSelection(selectedBookmarkPosition - 5); + break; + case Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE: + // Do nothing and let the default behavior run. + + case Snackbar.Callback.DISMISS_EVENT_MANUAL: + // Do nothing and let the default behavior run. + + case Snackbar.Callback.DISMISS_EVENT_SWIPE: + // Do nothing and let the default behavior run. + + case Snackbar.Callback.DISMISS_EVENT_TIMEOUT: + // Do nothing and let the default behavior run. + // The Snackbar was dismissed without the "Undo" button being pushed. default: // Delete each selected row. @@ -405,7 +447,11 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Convert `databaseIdLong` to an int. int databaseIdInt = (int) databaseIdLong; - // Delete the database row. + if (bookmarksDatabaseHandler.isFolder(databaseIdInt)) { + deleteBookmarkFolderContents(databaseIdInt); + } + + // Delete `databaseIdInt`. bookmarksDatabaseHandler.deleteBookmark(databaseIdInt); } break; @@ -438,7 +484,6 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Set a FloatingActionButton for creating new bookmarks. FloatingActionButton createBookmarkFAB = (FloatingActionButton) findViewById(R.id.create_bookmark_fab); - assert createBookmarkFAB != null; createBookmarkFAB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -504,11 +549,6 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma return true; } - @Override - public void onCancelCreateBookmark(DialogFragment dialogFragment) { - // Do nothing because the user selected `Cancel`. - } - @Override public void onCreateBookmark(DialogFragment dialogFragment) { // Get the `EditText`s from the `createBookmarkDialogFragment` and extract the strings. @@ -517,8 +557,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma EditText createBookmarkUrlEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext); String bookmarkUrlString = createBookmarkUrlEditText.getText().toString(); - // Convert the favoriteIcon Bitmap to a byte array. `0` is for lossless compression (the only option for a PNG). + // Convert the favoriteIcon Bitmap to a byte array. ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream(); + // `0` is for lossless compression (the only option for a PNG). MainWebViewActivity.favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream); byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray(); @@ -533,11 +574,6 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma bookmarksListView.setSelection(newBookmarkDisplayOrder); } - @Override - public void onCancelCreateBookmarkFolder(DialogFragment dialogFragment) { - // Do nothing because the user selected `Cancel`. - } - @Override public void onCreateBookmarkFolder(DialogFragment dialogFragment) { // Get `create_folder_name_edit_text` and extract the string. @@ -552,19 +588,20 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma String cannotCreateFolder = getResources().getString(R.string.cannot_create_folder) + " \"" + folderNameString + "\""; Snackbar.make(findViewById(R.id.bookmarks_coordinatorlayout), cannotCreateFolder, Snackbar.LENGTH_INDEFINITE).show(); } else { // Create the folder. - // Get the new folder icon. - RadioButton defaultFolderIconRadioButton = (RadioButton) dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobuttion); + // Get the new folder icon `Bitmap`. + RadioButton defaultFolderIconRadioButton = (RadioButton) dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton); Bitmap folderIconBitmap; if (defaultFolderIconRadioButton.isChecked()) { - // Get the default folder icon drawable and convert it to a `Bitmap`. `this` specifies the current context. - Drawable folderIconDrawable = ContextCompat.getDrawable(this, R.drawable.folder_blue_bitmap); + // Get the default folder icon `ImageView` from the `Dialog` and convert it to a `Bitmap`. + ImageView folderIconImageView = (ImageView) dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon); + Drawable folderIconDrawable = folderIconImageView.getDrawable(); BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable; folderIconBitmap = folderIconBitmapDrawable.getBitmap(); - } else { + } else { // Assign `favoriteIcon` from the `WebView`. folderIconBitmap = MainWebViewActivity.favoriteIcon; } - // Convert the folder `Bitmap` to a byte array. `0` is for lossless compression (the only option for a PNG). + // Convert `folderIconBitmap` 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(); @@ -583,11 +620,6 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } } - @Override - public void onCancelEditBookmark(DialogFragment dialogFragment) { - // Do nothing because the user selected `Cancel`. - } - @Override public void onSaveEditBookmark(DialogFragment dialogFragment) { // Get a long array with the the databaseId of the selected bookmark and convert it to an `int`. @@ -605,15 +637,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma if (currentBookmarkIconRadioButton.isChecked()) { // Update the bookmark without changing the favorite icon. bookmarksDatabaseHandler.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString); - } else { // Update the bookmark and the favorite icon. - // Get the new favorite icon from the `Dialog` and convert it into a `Bitmap`. - ImageView newFavoriteIconImageView = (ImageView) dialogFragment.getDialog().findViewById(R.id.edit_bookmark_web_page_favorite_icon); - Drawable newFavoriteIconDrawable = newFavoriteIconImageView.getDrawable(); - Bitmap newFavoriteIconBitmap = ((BitmapDrawable) newFavoriteIconDrawable).getBitmap(); - - // Convert `newFavoriteIconBitmap` into a Byte Array. + } else { // Update the bookmark using the `WebView` favorite icon. ByteArrayOutputStream newFavoriteIconByteArrayOutputStream = new ByteArrayOutputStream(); - newFavoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, newFavoriteIconByteArrayOutputStream); + MainWebViewActivity.favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, newFavoriteIconByteArrayOutputStream); byte[] newFavoriteIconByteArray = newFavoriteIconByteArrayOutputStream.toByteArray(); // Update the bookmark and the favorite icon. @@ -628,11 +654,6 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma bookmarksListView.setSelection(selectedBookmarkPosition); } - @Override - public void onCancelEditBookmarkFolder(DialogFragment dialogFragment) { - // Do nothing because the user selected `Cancel`. - } - @Override public void onSaveEditBookmarkFolder(DialogFragment dialogFragment) { // Get the new folder name. @@ -644,18 +665,17 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma int existingFoldersWithNewName = bookmarkFolderCursor.getCount(); bookmarkFolderCursor.close(); if ( ((existingFoldersWithNewName == 0) || newFolderNameString.equals(oldFolderNameString)) && !newFolderNameString.isEmpty()) { - // Get a long array with the the databaseId of the selected folder and convert it to an `int`. + // 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); - Bitmap folderIconBitmap; - // Prepare the favorite icon. + // Check if the favorite icon has changed. if (currentFolderIconRadioButton.isChecked()) { - // Update the folder name if it has changed. + // Update the folder name if it has changed without modifying the favorite icon. if (!newFolderNameString.equals(oldFolderNameString)) { bookmarksDatabaseHandler.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString); @@ -663,13 +683,16 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma updateBookmarksListView(currentFolder); bookmarksListView.setSelection(selectedBookmarkPosition); } - } else { // Prepare the new favorite icon. + } else { // Update the folder icon. + // Get the new folder icon `Bitmap`. + Bitmap folderIconBitmap; if (defaultFolderIconRadioButton.isChecked()) { - // Get the default folder icon drawable and convert it to a `Bitmap`. `this` specifies the current context. - Drawable folderIconDrawable = ContextCompat.getDrawable(this, R.drawable.folder_blue_bitmap); + // 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 { // Use the web page favorite icon. + } else { // Get the web page icon `ImageView` from the `Dialog`. folderIconBitmap = MainWebViewActivity.favoriteIcon; } @@ -688,13 +711,57 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma String cannot_rename_folder = getResources().getString(R.string.cannot_rename_folder) + " \"" + newFolderNameString + "\""; Snackbar.make(findViewById(R.id.bookmarks_coordinatorlayout), cannot_rename_folder, Snackbar.LENGTH_INDEFINITE).show(); } + + // Close the contextual action mode. + contextualActionMode.finish(); + } + + @Override + public void onMoveToFolder(DialogFragment dialogFragment) { + // Get the new folder database id. + ListView folderListView = (ListView) dialogFragment.getDialog().findViewById(R.id.move_to_folder_listview); + long[] newFolderLongArray = folderListView.getCheckedItemIds(); + + if (newFolderLongArray.length == 0) { // No new folder was selected. + Snackbar.make(findViewById(R.id.bookmarks_coordinatorlayout), getString(R.string.cannot_move_bookmarks), Snackbar.LENGTH_LONG).show(); + } else { // Move the selected bookmarks. + // Get the new folder database ID. + int newFolderDatabaseId = (int) newFolderLongArray[0]; + + // Instantiate `newFolderName`. + String newFolderName; + + if (newFolderDatabaseId == 0) { + // The new folder is the home folder, represented as `""` in the database. + newFolderName = ""; + } else { + // Get the new folder name from the database. + newFolderName = bookmarksDatabaseHandler.getFolderName(newFolderDatabaseId); + } + + // Get a long array with the the database ID of the selected bookmarks. + long[] selectedBookmarksLongArray = bookmarksListView.getCheckedItemIds(); + for (long databaseIdLong : selectedBookmarksLongArray) { + // Get `databaseIdInt` for each selected bookmark. + int databaseIdInt = (int) databaseIdLong; + + // Move the selected bookmark to the new folder. + bookmarksDatabaseHandler.moveToFolder(databaseIdInt, newFolderName); + } + + // Refresh the `ListView`. + updateBookmarksListView(currentFolder); + + // Close the contextual app bar. + contextualActionMode.finish(); + } } private void updateBookmarksListView(String folderName) { // Get a `Cursor` with the current contents of the bookmarks database. bookmarksCursor = bookmarksDatabaseHandler.getAllBookmarksCursorByDisplayOrder(folderName); - // Setup `bookmarksCursorAdapter` with `this` context. The `false` disables autoRequery. + // Setup `bookmarksCursorAdapter` with `this` context. `false` disables autoRequery. CursorAdapter bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { @@ -722,7 +789,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Make the font bold for folders. if (cursor.getInt(cursor.getColumnIndex(BookmarksDatabaseHandler.IS_FOLDER)) == 1) { - // The first argument is `null` because we don't want to chage the font. + // The first argument is `null` because we don't want to change the font. bookmarkNameTextView.setTypeface(null, Typeface.BOLD); } else { // Reset the font to default. bookmarkNameTextView.setTypeface(Typeface.DEFAULT); @@ -745,7 +812,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Get a `Cursor` with the current contents of the bookmarks database except for the specified database IDs. bookmarksCursor = bookmarksDatabaseHandler.getBookmarksCursorExcept(exceptIdLongArray, folderName); - // Setup `bookmarksCursorAdapter` with `this` context. The `false` disables autoRequery. + // Setup `bookmarksCursorAdapter` with `this` context. `false` disables autoRequery. CursorAdapter bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { @@ -773,7 +840,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Make the font bold for folders. if (cursor.getInt(cursor.getColumnIndex(BookmarksDatabaseHandler.IS_FOLDER)) == 1) { - // The first argument is `null` because we don't want to chage the font. + // The first argument is `null` because we don't want to change the font. bookmarkNameTextView.setTypeface(null, Typeface.BOLD); } else { // Reset the font to default. bookmarkNameTextView.setTypeface(Typeface.DEFAULT); @@ -784,4 +851,27 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Update the ListView. bookmarksListView.setAdapter(bookmarksCursorAdapter); } + + private void deleteBookmarkFolderContents(int databaseId) { + // Get the name of the folder. + String folderName = bookmarksDatabaseHandler.getFolderName(databaseId); + + // Get the contents of the folder. + Cursor folderCursor = bookmarksDatabaseHandler.getAllBookmarksCursorByDisplayOrder(folderName); + + for (int i = 0; i < folderCursor.getCount(); i++) { + // Move `folderCursor` to the current row. + folderCursor.moveToPosition(i); + + // Get the database ID of the item. + int itemDatabaseId = folderCursor.getInt(folderCursor.getColumnIndex(BookmarksDatabaseHandler._ID)); + + // If this is a folder, delete the contents first. + if (bookmarksDatabaseHandler.isFolder(itemDatabaseId)) { + deleteBookmarkFolderContents(itemDatabaseId); + } + + bookmarksDatabaseHandler.deleteBookmark(itemDatabaseId); + } + } } \ No newline at end of file