/*
- * Copyright 2016-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2016-2024 Soren Stoutner <soren@stoutner.com>.
*
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
*
* Privacy Browser Android is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
package com.stoutner.privacybrowser.activities
-import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.database.Cursor
import androidx.appcompat.app.ActionBar
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
+import androidx.core.graphics.drawable.toBitmap
import androidx.cursoradapter.widget.CursorAdapter
import androidx.fragment.app.DialogFragment
import androidx.preference.PreferenceManager
import com.google.android.material.snackbar.Snackbar
import com.stoutner.privacybrowser.R
-import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog.Companion.createBookmark
-import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog.CreateBookmarkListener
-import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog.Companion.createBookmarkFolder
-import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog.CreateBookmarkFolderListener
-import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog.Companion.bookmarkDatabaseId
-import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog.EditBookmarkListener
-import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDialog.Companion.folderDatabaseId
-import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDialog.EditBookmarkFolderListener
-import com.stoutner.privacybrowser.dialogs.MoveToFolderDialog.Companion.moveBookmarks
-import com.stoutner.privacybrowser.dialogs.MoveToFolderDialog.MoveToFolderListener
+import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog
+import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog
+import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog
+import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDialog
+import com.stoutner.privacybrowser.dialogs.MoveToFolderDialog
+import com.stoutner.privacybrowser.helpers.BOOKMARK_NAME
+import com.stoutner.privacybrowser.helpers.DISPLAY_ORDER
+import com.stoutner.privacybrowser.helpers.FAVORITE_ICON
+import com.stoutner.privacybrowser.helpers.FOLDER_ID
+import com.stoutner.privacybrowser.helpers.ID
+import com.stoutner.privacybrowser.helpers.IS_FOLDER
import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper
import java.io.ByteArrayOutputStream
import java.util.function.Consumer
// Define the public constants.
-const val CURRENT_FOLDER = "current_folder"
-const val CURRENT_TITLE = "current_title"
const val CURRENT_FAVORITE_ICON_BYTE_ARRAY = "current_favorite_icon_byte_array"
+const val CURRENT_FOLDER_ID = "current_folder_id"
+const val CURRENT_TITLE = "current_title"
// Define the private constants.
private const val CHECKED_BOOKMARKS_ARRAY_LIST = "checked_bookmarks_array_list"
-class BookmarksActivity : AppCompatActivity(), CreateBookmarkListener, CreateBookmarkFolderListener, EditBookmarkListener, EditBookmarkFolderListener, MoveToFolderListener {
+class BookmarksActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, EditBookmarkDialog.EditBookmarkListener,
+ EditBookmarkFolderDialog.EditBookmarkFolderListener, MoveToFolderDialog.MoveToFolderListener {
+
companion object {
// Define the public static variables, which are accessed from the bookmarks database view activity.
- var currentFolder: String = ""
+ var currentFolderId: Long = 0
var restartFromBookmarksDatabaseViewActivity = false
}
// Define the class variables.
private var bookmarksDeletedSnackbar: Snackbar? = null
+ private var checkingManyBookmarks = false
private var closeActivityAfterDismissingSnackbar = false
private var contextualActionMode: ActionMode? = null
+ private var sortBookmarksAlphabetically = false
// Declare the class variables.
private lateinit var appBar: ActionBar
private lateinit var currentFavoriteIconByteArray: ByteArray
private lateinit var moveBookmarkDownMenuItem: MenuItem
private lateinit var moveBookmarkUpMenuItem: MenuItem
- private lateinit var oldFolderNameString: String
+ private lateinit var moveToFolderMenuItem: MenuItem
override fun onCreate(savedInstanceState: Bundle?) {
// Get a handle for the shared preferences.
// Get the preferences.
val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
+ sortBookmarksAlphabetically = sharedPreferences.getBoolean(getString(R.string.sort_bookmarks_alphabetically_key), false)
// Disable screenshots if not allowed.
if (!allowScreenshots) {
val launchingIntent = intent
// Populate the variables from the launching intent.
- currentFolder = launchingIntent.getStringExtra(CURRENT_FOLDER)!!
+ currentFolderId = launchingIntent.getLongExtra(CURRENT_FOLDER_ID, HOME_FOLDER_ID)
val currentTitle = launchingIntent.getStringExtra(CURRENT_TITLE)!!
val currentUrl = launchingIntent.getStringExtra(CURRENT_URL)!!
currentFavoriteIconByteArray = launchingIntent.getByteArrayExtra(CURRENT_FAVORITE_ICON_BYTE_ARRAY)!!
// Initialize the database helper.
bookmarksDatabaseHelper = BookmarksDatabaseHelper(this)
- // Set a listener so that tapping a list item loads the URL or folder.
+ // Set a listener so that tapping a list item edits the bookmark or opens a folder.
bookmarksListView.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, _: Int, id: Long ->
// Convert the id from long to int to match the format of the bookmarks database.
val databaseId = id.toInt()
bookmarkCursor.moveToFirst()
// Act upon the bookmark according to the type.
- if (bookmarkCursor.getInt(bookmarkCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.IS_FOLDER)) == 1) { // The selected bookmark is a folder.
- // Update the current folder.
- currentFolder = bookmarkCursor.getString(bookmarkCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.BOOKMARK_NAME))
+ if (bookmarkCursor.getInt(bookmarkCursor.getColumnIndexOrThrow(IS_FOLDER)) == 1) { // The selected bookmark is a folder.
+ // Update the current folder ID.
+ currentFolderId = bookmarkCursor.getLong(bookmarkCursor.getColumnIndexOrThrow(FOLDER_ID))
// Load the new folder.
loadFolder()
} else { // The selected bookmark is not a folder.
// Instantiate the edit bookmark dialog.
- val editBookmarkDialog: DialogFragment = bookmarkDatabaseId(databaseId, currentFavoriteIconBitmap)
+ val editBookmarkDialog = EditBookmarkDialog.editBookmark(databaseId, currentFavoriteIconBitmap)
// Make it so.
editBookmarkDialog.show(supportFragmentManager, resources.getString(R.string.edit_bookmark))
menuInflater.inflate(R.menu.bookmarks_context_menu, menu)
// Set the title.
- if (currentFolder.isEmpty()) { // Use `R.string.bookmarks` if in the home folder.
+ if (currentFolderId == HOME_FOLDER_ID) { // The current folder is the home folder.
mode.setTitle(R.string.bookmarks)
} else { // Use the current folder name as the title.
- mode.title = currentFolder
+ mode.title = bookmarksDatabaseHelper.getFolderName(currentFolderId)
}
// Get handles for menu items that need to be selectively disabled.
moveBookmarkUpMenuItem = menu.findItem(R.id.move_bookmark_up)
moveBookmarkDownMenuItem = menu.findItem(R.id.move_bookmark_down)
+ moveToFolderMenuItem = menu.findItem(R.id.move_to_folder)
editBookmarkMenuItem = menu.findItem(R.id.edit_bookmark)
deleteBookmarksMenuItem = menu.findItem(R.id.delete_bookmark)
selectAllBookmarksMenuItem = menu.findItem(R.id.context_menu_select_all_bookmarks)
+ // Hide the move up and down menu items if bookmarks are sorted alphabetically.
+ if (sortBookmarksAlphabetically) {
+ moveBookmarkUpMenuItem.isVisible = false
+ moveBookmarkDownMenuItem.isVisible = false
+ }
+
// Disable the delete bookmarks menu item if a delete is pending.
deleteBookmarksMenuItem.isEnabled = !deletingBookmarks
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
- // Get a handle for the move to folder menu item.
- val moveToFolderMenuItem = menu.findItem(R.id.move_to_folder)
-
- // Get a Cursor with all of the folders.
- val folderCursor = bookmarksDatabaseHelper.allFolders
-
- // Display the move to folder menu item if at least one folder exists.
- moveToFolderMenuItem.isVisible = folderCursor.count > 0
+ // Display the move to folder menu item if at least one other folder exists.
+ moveToFolderMenuItem.isVisible = bookmarksDatabaseHelper.hasFoldersExceptDatabaseId(bookmarksListView.checkedItemIds)
// Make it so.
return true
}
- override fun onItemCheckedStateChanged(mode: ActionMode, position: Int, id: Long, checked: Boolean) {
- // Get the number of selected bookmarks.
- val numberOfSelectedBookmarks = bookmarksListView.checkedItemCount
-
- // Only process commands if at least one bookmark is selected. Otherwise, a context menu with 0 selected bookmarks is briefly displayed.
- if (numberOfSelectedBookmarks > 0) {
- // Adjust the action mode and the menu according to the number of selected bookmarks.
- if (numberOfSelectedBookmarks == 1) { // One bookmark is selected.
- // Show the applicable menu items.
- moveBookmarkUpMenuItem.isVisible = true
- moveBookmarkDownMenuItem.isVisible = true
- editBookmarkMenuItem.isVisible = true
-
- // Update the enabled status of the move icons.
- updateMoveIcons()
- } else { // More than one bookmark is selected.
- // Hide non-applicable `MenuItems`.
- moveBookmarkUpMenuItem.isVisible = false
- moveBookmarkDownMenuItem.isVisible = false
- editBookmarkMenuItem.isVisible = false
- }
+ override fun onItemCheckedStateChanged(actionMode: ActionMode, position: Int, id: Long, checked: Boolean) {
+ // Only update the UI if not checking many bookmarks. In that case, the flag will be reset on the last bookmark so the UI is only updated once.
+ if (!checkingManyBookmarks) {
+ // Get the number of selected bookmarks.
+ val numberOfSelectedBookmarks = bookmarksListView.checkedItemCount
+
+ // Only process commands if at least one bookmark is selected. Otherwise, a context menu with 0 selected bookmarks is briefly displayed.
+ if (numberOfSelectedBookmarks > 0) {
+ // Adjust the action mode and the menu according to the number of selected bookmarks.
+ if (numberOfSelectedBookmarks == 1) { // One bookmark is selected.
+ // Update the move menu items if the bookmarks are not sorted alphabetically.
+ if (!sortBookmarksAlphabetically) {
+ moveBookmarkUpMenuItem.isVisible = true
+ moveBookmarkDownMenuItem.isVisible = true
+ }
+
+ // Show the edit bookmark menu item.
+ editBookmarkMenuItem.isVisible = true
+
+ // Update the enabled status of the move icons if the bookmarks are not sorted alphabetically.
+ if (!sortBookmarksAlphabetically)
+ updateMoveIcons()
+ } else { // More than one bookmark is selected.
+ // Update the move menu items if the bookmarks are not sorted alphabetically.
+ if (!sortBookmarksAlphabetically) {
+ moveBookmarkUpMenuItem.isVisible = false
+ moveBookmarkDownMenuItem.isVisible = false
+ }
- // List the number of selected bookmarks in the subtitle.
- mode.subtitle = getString(R.string.selected, numberOfSelectedBookmarks)
+ // Hide the edit bookmark menu item.
+ editBookmarkMenuItem.isVisible = false
+ }
- // Show the select all menu item if all the bookmarks are not selected.
- selectAllBookmarksMenuItem.isVisible = (numberOfSelectedBookmarks != bookmarksListView.count)
+ // Display the move to folder menu item if at least one other folder exists.
+ moveToFolderMenuItem.isVisible = bookmarksDatabaseHelper.hasFoldersExceptDatabaseId(bookmarksListView.checkedItemIds)
+
+ // List the number of selected bookmarks in the subtitle.
+ actionMode.subtitle = getString(R.string.selected, numberOfSelectedBookmarks)
+
+ // Show the select all menu item if all the bookmarks are not selected.
+ selectAllBookmarksMenuItem.isVisible = (numberOfSelectedBookmarks != bookmarksListView.count)
+ }
}
}
override fun onActionItemClicked(actionMode: ActionMode, menuItem: MenuItem): Boolean {
// Declare the variables.
- val selectedBookmarkNewPosition: Int
- val selectedBookmarksPositionsSparseBooleanArray: SparseBooleanArray
+ val checkedBookmarkNewPosition: Int
+ val checkedBookmarksPositionsSparseBooleanArray: SparseBooleanArray
- // Initialize the selected bookmark position.
- var selectedBookmarkPosition = 0
+ // Initialize the checked bookmark position.
+ var checkedBookmarkPosition = 0
// Get the menu item ID.
val menuItemId = menuItem.itemId
// Run the commands according to the selected action item.
if (menuItemId == R.id.move_bookmark_up) { // Move the bookmark up.
// Get the array of checked bookmark positions.
- selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions
+ checkedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions
// Get the position of the bookmark that is selected. If other bookmarks have previously been selected they will be included in the sparse boolean array with a value of `false`.
- for (i in 0 until selectedBookmarksPositionsSparseBooleanArray.size()) {
+ for (i in 0 until checkedBookmarksPositionsSparseBooleanArray.size()) {
// Check to see if the value for the bookmark is true, meaning it is currently selected.
- if (selectedBookmarksPositionsSparseBooleanArray.valueAt(i)) {
+ if (checkedBookmarksPositionsSparseBooleanArray.valueAt(i)) {
// Only one bookmark should have a value of `true` when move bookmark up is enabled.
- selectedBookmarkPosition = selectedBookmarksPositionsSparseBooleanArray.keyAt(i)
+ checkedBookmarkPosition = checkedBookmarksPositionsSparseBooleanArray.keyAt(i)
}
}
- // Calculate the new position of the selected bookmark.
- selectedBookmarkNewPosition = selectedBookmarkPosition - 1
+ // Calculate the new position of the checked bookmark.
+ checkedBookmarkNewPosition = checkedBookmarkPosition - 1
+
+ // Get the bookmarks count.
+ val bookmarksCount = bookmarksListView.count
// Iterate through the bookmarks.
- for (i in 0 until bookmarksListView.count) {
+ for (i in 0 until bookmarksCount) {
// Get the database ID for the current bookmark.
val currentBookmarkDatabaseId = bookmarksListView.getItemIdAtPosition(i).toInt()
// Update the display order for the current bookmark.
- if (i == selectedBookmarkPosition) { // The current bookmark is the selected bookmark.
+ if (i == checkedBookmarkPosition) { // The current bookmark is the selected bookmark.
// Move the current bookmark up one.
bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i - 1)
- } else if ((i + 1) == selectedBookmarkPosition) { // The current bookmark is immediately above the selected bookmark.
+ } else if ((i + 1) == checkedBookmarkPosition) { // The current bookmark is immediately above the selected bookmark.
// Move the current bookmark down one.
bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i + 1)
} else { // The current bookmark is not changing positions.
bookmarksCursor.moveToPosition(i)
// Update the display order only if it is not correct in the database. This fixes problems where the display order somehow got out of sync.
- if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.DISPLAY_ORDER)) != i)
+ if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(DISPLAY_ORDER)) != i)
bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i)
}
}
// Update the bookmarks cursor with the current contents of the bookmarks database.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
// Scroll to the new bookmark position.
- scrollBookmarks(selectedBookmarkNewPosition)
+ scrollBookmarks(checkedBookmarkNewPosition)
// Update the enabled status of the move icons.
updateMoveIcons()
} else if (menuItemId == R.id.move_bookmark_down) { // Move the bookmark down.
// Get the array of checked bookmark positions.
- selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions
+ checkedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions
- // Get the position of the bookmark that is selected. If other bookmarks have previously been selected they will be included in the sparse boolean array with a value of `false`.
- for (i in 0 until selectedBookmarksPositionsSparseBooleanArray.size()) {
+ // Get the position of the bookmark that is selected. If other bookmarks have previously been checked they will be included in the sparse boolean array with a value of `false`.
+ for (i in 0 until checkedBookmarksPositionsSparseBooleanArray.size()) {
// Check to see if the value for the bookmark is true, meaning it is currently selected.
- if (selectedBookmarksPositionsSparseBooleanArray.valueAt(i)) {
+ if (checkedBookmarksPositionsSparseBooleanArray.valueAt(i)) {
// Only one bookmark should have a value of `true` when move bookmark down is enabled.
- selectedBookmarkPosition = selectedBookmarksPositionsSparseBooleanArray.keyAt(i)
+ checkedBookmarkPosition = checkedBookmarksPositionsSparseBooleanArray.keyAt(i)
}
}
- // Calculate the new position of the selected bookmark.
- selectedBookmarkNewPosition = selectedBookmarkPosition + 1
+ // Calculate the new position of the checked bookmark.
+ checkedBookmarkNewPosition = checkedBookmarkPosition + 1
// Iterate through the bookmarks.
for (i in 0 until bookmarksListView.count) {
val currentBookmarkDatabaseId = bookmarksListView.getItemIdAtPosition(i).toInt()
// Update the display order for the current bookmark.
- if (i == selectedBookmarkPosition) { // The current bookmark is the selected bookmark.
+ if (i == checkedBookmarkPosition) { // The current bookmark is the checked bookmark.
// Move the current bookmark down one.
bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i + 1)
- } else if (i - 1 == selectedBookmarkPosition) { // The current bookmark is immediately below the selected bookmark.
+ } else if ((i - 1) == checkedBookmarkPosition) { // The current bookmark is immediately below the checked bookmark.
// Move the bookmark below the selected bookmark up one.
bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i - 1)
} else { // The current bookmark is not changing positions.
bookmarksCursor.moveToPosition(i)
// Update the display order only if it is not correct in the database. This fixes problems where the display order somehow got out of sync.
- if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.DISPLAY_ORDER)) != i) {
+ if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(DISPLAY_ORDER)) != i) {
bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i)
}
}
}
// Update the bookmarks cursor with the current contents of the bookmarks database.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
// Scroll to the new bookmark position.
- scrollBookmarks(selectedBookmarkNewPosition)
+ scrollBookmarks(checkedBookmarkNewPosition)
// Update the enabled status of the move icons.
updateMoveIcons()
} else if (menuItemId == R.id.move_to_folder) { // Move to folder.
// Instantiate the move to folder alert dialog.
- val moveToFolderDialog: DialogFragment = moveBookmarks(currentFolder, bookmarksListView.checkedItemIds)
+ val moveToFolderDialog = MoveToFolderDialog.moveBookmarks(currentFolderId, bookmarksListView.checkedItemIds)
// Show the move to folder alert dialog.
moveToFolderDialog.show(supportFragmentManager, resources.getString(R.string.move_to_folder))
} else if (menuItemId == R.id.edit_bookmark) {
// Get the array of checked bookmark positions.
- selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions
+ checkedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions
// Get the position of the bookmark that is selected. If other bookmarks have previously been selected they will be included in the sparse boolean array with a value of `false`.
- for (i in 0 until selectedBookmarksPositionsSparseBooleanArray.size()) {
+ for (i in 0 until checkedBookmarksPositionsSparseBooleanArray.size()) {
// Check to see if the value for the bookmark is true, meaning it is currently selected.
- if (selectedBookmarksPositionsSparseBooleanArray.valueAt(i)) {
+ if (checkedBookmarksPositionsSparseBooleanArray.valueAt(i)) {
// Only one bookmark should have a value of `true` when move edit bookmark is enabled.
- selectedBookmarkPosition = selectedBookmarksPositionsSparseBooleanArray.keyAt(i)
+ checkedBookmarkPosition = checkedBookmarksPositionsSparseBooleanArray.keyAt(i)
}
}
// Move the cursor to the selected position.
- bookmarksCursor.moveToPosition(selectedBookmarkPosition)
+ bookmarksCursor.moveToPosition(checkedBookmarkPosition)
// Get the selected bookmark database ID.
- val databaseId = bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.ID))
+ val databaseId = bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(ID))
// Show the edit bookmark or edit bookmark folder dialog.
- if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.IS_FOLDER)) == 1) { // A folder is selected.
- // Save the current folder name, which is used in `onSaveBookmarkFolder()`.
- oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.BOOKMARK_NAME))
-
+ if (bookmarksCursor.getInt(bookmarksCursor.getColumnIndexOrThrow(IS_FOLDER)) == 1) { // A folder is selected.
// Instantiate the edit bookmark folder dialog.
- val editFolderDialog: DialogFragment = folderDatabaseId(databaseId, currentFavoriteIconBitmap)
+ val editFolderDialog = EditBookmarkFolderDialog.editFolder(databaseId, currentFavoriteIconBitmap)
// Make it so.
editFolderDialog.show(supportFragmentManager, resources.getString(R.string.edit_folder))
} else { // A bookmark is selected.
// Instantiate the edit bookmark dialog.
- val editBookmarkDialog: DialogFragment = bookmarkDatabaseId(databaseId, currentFavoriteIconBitmap)
+ val editBookmarkDialog = EditBookmarkDialog.editBookmark(databaseId, currentFavoriteIconBitmap)
// Make it so.
editBookmarkDialog.show(supportFragmentManager, resources.getString(R.string.edit_bookmark))
// Set the deleting bookmarks flag, which prevents the delete menu item from being enabled until the current process finishes.
deletingBookmarks = true
- // Get an array of the selected row IDs.
- val selectedBookmarksIdsLongArray = bookmarksListView.checkedItemIds
+ // Get an array of the checked row IDs.
+ val checkedBookmarksIdsLongArray = bookmarksListView.checkedItemIds
// Initialize a variable to count the number of bookmarks to delete.
var numberOfBookmarksToDelete = 0
// Count the number of bookmarks to delete.
- for (databaseIdLong in selectedBookmarksIdsLongArray) {
+ for (databaseIdLong in checkedBookmarksIdsLongArray) {
// Convert the database ID long to an int.
val databaseIdInt = databaseIdLong.toInt()
}
// Get an array of checked bookmarks. `.clone()` makes a copy that won't change if the list view is reloaded, which is needed for re-selecting the bookmarks on undelete.
- selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions.clone()
+ checkedBookmarksPositionsSparseBooleanArray = bookmarksListView.checkedItemPositions.clone()
// Update the bookmarks cursor with the current contents of the bookmarks database except for the specified database IDs.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrderExcept(selectedBookmarksIdsLongArray, currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabeticallyExcept(checkedBookmarksIdsLongArray, currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrderExcept(checkedBookmarksIdsLongArray, currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
bookmarksDeletedSnackbar = Snackbar.make(findViewById(R.id.bookmarks_coordinatorlayout), getString(R.string.bookmarks_deleted, numberOfBookmarksToDelete), Snackbar.LENGTH_LONG)
.setAction(R.string.undo) { } // Do nothing because everything will be handled by `onDismissed()` below.
.addCallback(object : Snackbar.Callback() {
- @SuppressLint("SwitchIntDef") // Ignore the lint warning about not handling the other possible events as they are covered by `default:`.
override fun onDismissed(snackbar: Snackbar, event: Int) {
if (event == DISMISS_EVENT_ACTION) { // The user pushed the undo button.
// Update the bookmarks cursor with the current contents of the bookmarks database, including the "deleted" bookmarks.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabetically(currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
- // Re-select the previously selected bookmarks.
- for (i in 0 until selectedBookmarksPositionsSparseBooleanArray.size())
- bookmarksListView.setItemChecked(selectedBookmarksPositionsSparseBooleanArray.keyAt(i), true)
+ // Get the number of checked bookmarks.
+ val numberOfCheckedBookmarks = checkedBookmarksPositionsSparseBooleanArray.size()
+
+ // Set the checking many bookmarks flag.
+ checkingManyBookmarks = true
+
+ // Re-check the previously checked bookmarks.
+ for (i in 0 until numberOfCheckedBookmarks) {
+ // Reset the checking many bookmarks flag on the last bookmark so the UI is updated.
+ if (i == (numberOfCheckedBookmarks - 1))
+ checkingManyBookmarks = false
+
+ // Check the bookmark.
+ bookmarksListView.setItemChecked(checkedBookmarksPositionsSparseBooleanArray.keyAt(i), true)
+ }
} else { // The snackbar was dismissed without the undo button being pushed.
// Delete each selected bookmark.
- for (databaseIdLong in selectedBookmarksIdsLongArray) {
+ for (databaseIdLong in checkedBookmarksIdsLongArray) {
// Convert the database long ID to an int.
val databaseIdInt = databaseIdLong.toInt()
bookmarksDatabaseHelper.deleteBookmark(databaseIdInt)
}
- // Update the display order.
- for (i in 0 until bookmarksListView.count) {
- // Get the database ID for the current bookmark.
- val currentBookmarkDatabaseId = bookmarksListView.getItemIdAtPosition(i).toInt()
-
- // Move bookmarks cursor 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.getColumnIndexOrThrow(BookmarksDatabaseHelper.DISPLAY_ORDER)) != i)
- bookmarksDatabaseHelper.updateDisplayOrder(currentBookmarkDatabaseId, i)
- }
+ // Recalculate the display order of the current folder.
+ bookmarksDatabaseHelper.recalculateFolderContentsDisplayOrder(currentFolderId)
}
// Reset the deleting bookmarks flag.
deleteBookmarksMenuItem.isEnabled = true
// Close the activity if back has been pressed.
- if (closeActivityAfterDismissingSnackbar)
+ if (closeActivityAfterDismissingSnackbar) {
+ // Close the bookmarks drawer and reload the bookmarks list view when returning to the main WebView activity.
+ MainWebViewActivity.restartFromBookmarksActivity = true
+
+ // Finish the activity.
finish()
+ }
}
})
// Get the total number of bookmarks.
val numberOfBookmarks = bookmarksListView.count
+ // Set the checking many bookmarks flag.
+ checkingManyBookmarks = true
+
// Select them all.
for (i in 0 until numberOfBookmarks) {
+ // Reset the checking many bookmarks flag on the last bookmark so the UI is updated.
+ if (i == (numberOfBookmarks - 1))
+ checkingManyBookmarks = false
+
+ // Check the bookmark.
bookmarksListView.setItemChecked(i, true)
}
}
// Set the create new bookmark folder FAB to display the alert dialog.
createBookmarkFolderFab.setOnClickListener {
// Create a create bookmark folder dialog.
- val createBookmarkFolderDialog: DialogFragment = createBookmarkFolder(currentFavoriteIconBitmap)
+ val createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentFavoriteIconBitmap)
// Show the create bookmark folder dialog.
createBookmarkFolderDialog.show(supportFragmentManager, getString(R.string.create_folder))
// Set the create new bookmark FAB to display the alert dialog.
createBookmarkFab.setOnClickListener {
// Instantiate the create bookmark dialog.
- val createBookmarkDialog: DialogFragment = createBookmark(currentUrl, currentTitle, currentFavoriteIconBitmap)
+ val createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentUrl, currentTitle, currentFavoriteIconBitmap)
// Display the create bookmark dialog.
createBookmarkDialog.show(supportFragmentManager, resources.getString(R.string.create_bookmark))
// Restore the state if the app has been restarted.
if (savedInstanceState != null) {
// Restore the current folder.
- currentFolder = savedInstanceState.getString(CURRENT_FOLDER)!!
+ currentFolderId = savedInstanceState.getLong(CURRENT_FOLDER_ID, HOME_FOLDER_ID)
// Update the bookmarks list view after it has loaded.
bookmarksListView.post {
}
}
- public override fun onSaveInstanceState(savedInstanceState: Bundle) {
+ public override fun onSaveInstanceState(outState: Bundle) {
// Run the default commands.
- super.onSaveInstanceState(savedInstanceState)
+ super.onSaveInstanceState(outState)
// Get the sparse boolean array of the checked items.
val checkedBookmarksSparseBooleanArray = bookmarksListView.checkedItemPositions
}
}
- // Store the variables in the saved instance state.
- savedInstanceState.putString(CURRENT_FOLDER, currentFolder)
- savedInstanceState.putIntegerArrayList(CHECKED_BOOKMARKS_ARRAY_LIST, checkedBookmarksArrayList)
+ // Store the variables in the out state.
+ outState.putLong(CURRENT_FOLDER_ID, currentFolderId)
+ outState.putIntegerArrayList(CHECKED_BOOKMARKS_ARRAY_LIST, checkedBookmarksArrayList)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Run the command according to the selected option.
if (menuItemId == android.R.id.home) { // Home. The home arrow is identified as `android.R.id.home`, not just `R.id.home`.
- if (currentFolder.isEmpty()) { // Currently in the home folder.
+ if (currentFolderId == HOME_FOLDER_ID) { // The current folder is the home folder.
// Prepare to finish the activity.
prepareFinish()
} else { // Currently in a subfolder.
// Set the former parent folder as the current folder.
- currentFolder = bookmarksDatabaseHelper.getParentFolderName(currentFolder)
+ currentFolderId = bookmarksDatabaseHelper.getParentFolderId(currentFolderId)
// Load the new current folder.
loadFolder()
// Get the total number of bookmarks.
val numberOfBookmarks = bookmarksListView.count
+ // Set the checking many bookmarks flag.
+ checkingManyBookmarks = true
+
// Select them all.
for (i in 0 until numberOfBookmarks) {
+ // Reset the checking many bookmarks flag on the last bookmark so the UI is updated.
+ if (i == (numberOfBookmarks - 1))
+ checkingManyBookmarks = false
+
+ // Check the bookmark.
bookmarksListView.setItemChecked(i, true)
}
} else if (menuItemId == R.id.bookmarks_database_view) {
return true
}
- override fun onCreateBookmark(dialogFragment: DialogFragment, favoriteIconBitmap: Bitmap) {
+ override fun createBookmark(dialogFragment: DialogFragment) {
// Get the alert dialog from the fragment.
val dialog = dialogFragment.dialog!!
- // Get the views from the dialog fragment.
- val createBookmarkNameEditText = dialog.findViewById<EditText>(R.id.create_bookmark_name_edittext)
- val createBookmarkUrlEditText = dialog.findViewById<EditText>(R.id.create_bookmark_url_edittext)
+ // Get handles for the views from the dialog fragment.
+ val webpageFavoriteIconRadioButton = dialog.findViewById<RadioButton>(R.id.webpage_favorite_icon_radiobutton)
+ val webpageFavoriteIconImageView = dialog.findViewById<ImageView>(R.id.webpage_favorite_icon_imageview)
+ val customIconImageView = dialog.findViewById<ImageView>(R.id.custom_icon_imageview)
+ val bookmarkNameEditText = dialog.findViewById<EditText>(R.id.bookmark_name_edittext)
+ val bookmarkUrlEditText = dialog.findViewById<EditText>(R.id.bookmark_url_edittext)
+
+ // Get the strings from the edit texts.
+ val bookmarkNameString = bookmarkNameEditText.text.toString()
+ val bookmarkUrlString = bookmarkUrlEditText.text.toString()
- // Extract the strings from the edit texts.
- val bookmarkNameString = createBookmarkNameEditText.text.toString()
- val bookmarkUrlString = createBookmarkUrlEditText.text.toString()
+ // Get the selected favorite icon drawable.
+ val favoriteIconDrawable = if (webpageFavoriteIconRadioButton.isChecked) // The webpage favorite icon is checked.
+ webpageFavoriteIconImageView.drawable
+ else // The custom favorite icon is checked.
+ customIconImageView.drawable
+
+ // Convert the favorite icon drawable to a bitmap. Once the minimum API >= 33, this can use Bitmap.Config.RGBA_1010102.
+ val favoriteIconBitmap = favoriteIconDrawable.toBitmap(128, 128, Bitmap.Config.ARGB_8888)
// Create a favorite icon byte array output stream.
val favoriteIconByteArrayOutputStream = ByteArrayOutputStream()
val newBookmarkDisplayOrder = bookmarksListView.count
// Create the bookmark.
- bookmarksDatabaseHelper.createBookmark(bookmarkNameString, bookmarkUrlString, currentFolder, newBookmarkDisplayOrder, favoriteIconByteArray)
+ bookmarksDatabaseHelper.createBookmark(bookmarkNameString, bookmarkUrlString, currentFolderId, newBookmarkDisplayOrder, favoriteIconByteArray)
// Update the bookmarks cursor with the current contents of this folder.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabetically(currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
bookmarksListView.setSelection(newBookmarkDisplayOrder)
}
- override fun onCreateBookmarkFolder(dialogFragment: DialogFragment, favoriteIconBitmap: Bitmap) {
+ override fun createBookmarkFolder(dialogFragment: DialogFragment) {
// Get the dialog from the dialog fragment.
val dialog = dialogFragment.dialog!!
// Get handles for the views in the dialog fragment.
+ val defaultFolderIconRadioButton = dialog.findViewById<RadioButton>(R.id.default_folder_icon_radiobutton)
+ val defaultFolderIconImageView = dialog.findViewById<ImageView>(R.id.default_folder_icon_imageview)
+ val webpageFavoriteIconRadioButton = dialog.findViewById<RadioButton>(R.id.webpage_favorite_icon_radiobutton)
+ val webpageFavoriteIconImageView = dialog.findViewById<ImageView>(R.id.webpage_favorite_icon_imageview)
+ val customIconImageView = dialog.findViewById<ImageView>(R.id.custom_icon_imageview)
val folderNameEditText = dialog.findViewById<EditText>(R.id.folder_name_edittext)
- val defaultIconRadioButton = dialog.findViewById<RadioButton>(R.id.default_icon_radiobutton)
- val defaultIconImageView = dialog.findViewById<ImageView>(R.id.default_icon_imageview)
- // Get new folder name string.
+ // Get the folder name string.
val folderNameString = folderNameEditText.text.toString()
- // Set the folder icon bitmap according to the dialog.
- val folderIconBitmap = if (defaultIconRadioButton.isChecked) { // Use the default folder icon.
- // Get the default folder icon drawable.
- val folderIconDrawable = defaultIconImageView.drawable
+ // Get the selected folder icon drawable.
+ val folderIconDrawable = if (defaultFolderIconRadioButton.isChecked) // Use the default folder icon.
+ defaultFolderIconImageView.drawable
+ else if (webpageFavoriteIconRadioButton.isChecked) // Use the webpage favorite icon.
+ webpageFavoriteIconImageView.drawable
+ else // Use the custom icon.
+ customIconImageView.drawable
- // Convert the folder icon drawable to a bitmap drawable.
- val folderIconBitmapDrawable = folderIconDrawable as BitmapDrawable
+ // Cast the folder icon bitmap to a bitmap drawable.
+ val folderIconBitmapDrawable = folderIconDrawable as BitmapDrawable
- // Convert the folder icon bitmap drawable to a bitmap.
- folderIconBitmapDrawable.bitmap
- } else { // Use the WebView favorite icon.
- // Copy the favorite icon bitmap to the folder icon bitmap.
- favoriteIconBitmap
- }
+ // Convert the folder icon bitmap drawable to a bitmap.
+ val folderIconBitmap = folderIconBitmapDrawable.bitmap
// Create a folder icon byte array output stream.
val folderIconByteArrayOutputStream = ByteArrayOutputStream()
// Move all the bookmarks down one in the display order.
for (i in 0 until bookmarksListView.count) {
val databaseId = bookmarksListView.getItemIdAtPosition(i).toInt()
- bookmarksDatabaseHelper.updateDisplayOrder(databaseId, i + 1)
+ bookmarksDatabaseHelper.updateDisplayOrder(databaseId, displayOrder = i + 1)
}
// Create the folder, which will be placed at the top of the list view.
- bookmarksDatabaseHelper.createFolder(folderNameString, currentFolder, folderIconByteArray)
+ bookmarksDatabaseHelper.createFolder(folderNameString, currentFolderId, displayOrder = 0, folderIconByteArray)
// Update the bookmarks cursor with the contents of the current folder.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabetically(currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
bookmarksListView.setSelection(0)
}
- override fun onSaveBookmark(dialogFragment: DialogFragment, selectedBookmarkDatabaseId: Int, favoriteIconBitmap: Bitmap) {
+ override fun saveBookmark(dialogFragment: DialogFragment, selectedBookmarkDatabaseId: Int) {
// Get the dialog from the dialog fragment.
val dialog = dialogFragment.dialog!!
// Get handles for the views from the dialog fragment.
+ val currentIconRadioButton = dialog.findViewById<RadioButton>(R.id.current_icon_radiobutton)
+ val webpageFavoriteIconRadioButton = dialog.findViewById<RadioButton>(R.id.webpage_favorite_icon_radiobutton)
+ val webpageFavoriteIconImageView = dialog.findViewById<ImageView>(R.id.webpage_favorite_icon_imageview)
+ val customIconImageView = dialog.findViewById<ImageView>(R.id.custom_icon_imageview)
val bookmarkNameEditText = dialog.findViewById<EditText>(R.id.bookmark_name_edittext)
val bookmarkUrlEditText = dialog.findViewById<EditText>(R.id.bookmark_url_edittext)
- val currentIconRadioButton = dialog.findViewById<RadioButton>(R.id.current_icon_radiobutton)
- // Get the bookmark strings.
+ // Get the strings from the edit texts.
val bookmarkNameString = bookmarkNameEditText.text.toString()
val bookmarkUrlString = bookmarkUrlEditText.text.toString()
if (currentIconRadioButton.isChecked) { // Update the bookmark without changing the favorite icon.
bookmarksDatabaseHelper.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString)
} else { // Update the bookmark using the WebView favorite icon.
+ // Get the selected favorite icon drawable.
+ val favoriteIconDrawable = if (webpageFavoriteIconRadioButton.isChecked) // The webpage favorite icon is checked.
+ webpageFavoriteIconImageView.drawable
+ else // The custom icon is checked.
+ customIconImageView.drawable
+
+ // Convert the favorite icon drawable to a bitmap. Once the minimum API >= 33, this can use Bitmap.Config.RGBA_1010102.
+ val favoriteIconBitmap = favoriteIconDrawable.toBitmap(128, 128, Bitmap.Config.ARGB_8888)
+
// Create a favorite icon byte array output stream.
val newFavoriteIconByteArrayOutputStream = ByteArrayOutputStream()
contextualActionMode?.finish()
// Update the bookmarks cursor with the contents of the current folder.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabetically(currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
}
- override fun onSaveBookmarkFolder(dialogFragment: DialogFragment, selectedFolderDatabaseId: Int, favoriteIconBitmap: Bitmap) {
+ override fun saveBookmarkFolder(dialogFragment: DialogFragment, selectedFolderDatabaseId: Int) {
// Get the dialog from the dialog fragment.
val dialog = dialogFragment.dialog!!
// Get handles for the views from the dialog fragment.
val currentFolderIconRadioButton = dialog.findViewById<RadioButton>(R.id.current_icon_radiobutton)
- val defaultFolderIconRadioButton = dialog.findViewById<RadioButton>(R.id.default_icon_radiobutton)
- val defaultFolderIconImageView = dialog.findViewById<ImageView>(R.id.default_icon_imageview)
- val editFolderNameEditText = dialog.findViewById<EditText>(R.id.folder_name_edittext)
+ val defaultFolderIconRadioButton = dialog.findViewById<RadioButton>(R.id.default_folder_icon_radiobutton)
+ val defaultFolderIconImageView = dialog.findViewById<ImageView>(R.id.default_folder_icon_imageview)
+ val webpageFavoriteIconRadioButton = dialog.findViewById<RadioButton>(R.id.webpage_favorite_icon_radiobutton)
+ val webpageFavoriteIconImageView = dialog.findViewById<ImageView>(R.id.webpage_favorite_icon_imageview)
+ val customIconImageView = dialog.findViewById<ImageView>(R.id.custom_icon_imageview)
+ val folderNameEditText = dialog.findViewById<EditText>(R.id.folder_name_edittext)
// Get the new folder name.
- val newFolderNameString = editFolderNameEditText.text.toString()
+ val newFolderName = folderNameEditText.text.toString()
- // Check if the favorite icon has changed.
+ // Check if the folder icon has changed.
if (currentFolderIconRadioButton.isChecked) { // Only the name has changed.
// Update the name in the database.
- bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString)
+ bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, newFolderName)
} else { // The icon has changed.
- // Populate the new folder icon bitmap.
- val folderIconBitmap: Bitmap = if (defaultFolderIconRadioButton.isChecked) {
- // Get the default folder icon drawable.
- val folderIconDrawable = defaultFolderIconImageView.drawable
-
- // Convert the folder icon drawable to a bitmap drawable.
- val folderIconBitmapDrawable = folderIconDrawable as BitmapDrawable
-
- // Convert the folder icon bitmap drawable to a bitmap.
- folderIconBitmapDrawable.bitmap
- } else { // Use the WebView favorite icon.
- // Copy the favorite icon bitmap to the folder icon bitmap.
- favoriteIconBitmap
- }
-
- // Create a folder icon byte array output stream.
+ // Get the selected folder icon drawable.
+ val folderIconDrawable = if (defaultFolderIconRadioButton.isChecked) // The default folder icon is checked.
+ defaultFolderIconImageView.drawable
+ else if (webpageFavoriteIconRadioButton.isChecked) // The webpage favorite icon is checked.
+ webpageFavoriteIconImageView.drawable
+ else // The custom icon is checked.
+ customIconImageView.drawable
+
+ // Convert the folder icon drawable to a bitmap. Once the minimum API >= 33, this can use Bitmap.Config.RGBA_1010102.
+ val folderIconBitmap = folderIconDrawable.toBitmap(128, 128, Bitmap.Config.ARGB_8888)
+
+ // Create a new folder icon byte array output stream.
val newFolderIconByteArrayOutputStream = ByteArrayOutputStream()
// Convert the folder icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
val newFolderIconByteArray = newFolderIconByteArrayOutputStream.toByteArray()
// Update the database.
- if (!currentFolderIconRadioButton.isChecked && newFolderNameString == oldFolderNameString) // Only the icon has changed.
- bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, newFolderIconByteArray)
- else // The folder icon and the name have changed.
- bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString, newFolderIconByteArray)
+ bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, newFolderName, newFolderIconByteArray)
}
// Update the bookmarks cursor with the current contents of this folder.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabetically(currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
val newFolderDatabaseId = newFolderLongArray[0].toInt()
// Set the new folder name.
- val newFolderName = if (newFolderDatabaseId == 0) {
- // The new folder is the home folder, represented as `""` in the database.
- ""
- } else {
+ val newFolderId = if (newFolderDatabaseId == HOME_FOLDER_DATABASE_ID)
+ // The new folder is the home folder.
+ HOME_FOLDER_ID
+ else
// Get the new folder name from the database.
- bookmarksDatabaseHelper.getFolderName(newFolderDatabaseId)
- }
+ bookmarksDatabaseHelper.getFolderId(newFolderDatabaseId)
// Get a long array with the the database ID of the selected bookmarks.
val selectedBookmarksLongArray = bookmarksListView.checkedItemIds
val databaseIdInt = databaseIdLong.toInt()
// Move the selected bookmark to the new folder.
- bookmarksDatabaseHelper.moveToFolder(databaseIdInt, newFolderName)
+ bookmarksDatabaseHelper.moveToFolder(databaseIdInt, newFolderId)
}
+ // Recalculate the display order of the current folder.
+ bookmarksDatabaseHelper.recalculateFolderContentsDisplayOrder(currentFolderId)
+
// Update the bookmarks cursor with the current contents of this folder.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabetically(currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Update the list view.
bookmarksCursorAdapter.changeCursor(bookmarksCursor)
}
private fun countBookmarkFolderContents(folderDatabaseId: Int): Int {
- // Get the name of the folder.
- val folderName = bookmarksDatabaseHelper.getFolderName(folderDatabaseId)
+ // Get the folder ID.
+ val folderId = bookmarksDatabaseHelper.getFolderId(folderDatabaseId)
// Get the contents of the folder.
- val folderCursor = bookmarksDatabaseHelper.getBookmarkIds(folderName)
+ val folderCursor = bookmarksDatabaseHelper.getBookmarkAndFolderIds(folderId)
// Initialize the bookmark counter.
var bookmarkCounter = 0
folderCursor.moveToPosition(i)
// Get the database ID of the item.
- val itemDatabaseId = folderCursor.getInt(folderCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.ID))
+ val itemDatabaseId = folderCursor.getInt(folderCursor.getColumnIndexOrThrow(ID))
// If this is a folder, recursively count the contents first.
if (bookmarksDatabaseHelper.isFolder(itemDatabaseId))
}
private fun deleteBookmarkFolderContents(folderDatabaseId: Int) {
- // Get the name of the folder.
- val folderName = bookmarksDatabaseHelper.getFolderName(folderDatabaseId)
+ // Get the folder ID.
+ val folderId = bookmarksDatabaseHelper.getFolderId(folderDatabaseId)
// Get the contents of the folder.
- val folderCursor = bookmarksDatabaseHelper.getBookmarkIds(folderName)
+ val folderCursor = bookmarksDatabaseHelper.getBookmarkAndFolderIds(folderId)
// Delete each of the bookmarks in the folder.
for (i in 0 until folderCursor.count) {
folderCursor.moveToPosition(i)
// Get the database ID of the item.
- val itemDatabaseId = folderCursor.getInt(folderCursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.ID))
+ val itemDatabaseId = folderCursor.getInt(folderCursor.getColumnIndexOrThrow(ID))
// If this is a folder, recursively delete the contents first.
if (bookmarksDatabaseHelper.isFolder(itemDatabaseId))
bookmarksDeletedSnackbar!!.dismiss()
} else { // Go home immediately.
// Update the bookmarks folder for the bookmarks drawer in the main WebView activity.
- MainWebViewActivity.currentBookmarksFolder = currentFolder
+ MainWebViewActivity.currentBookmarksFolderId = currentFolderId
// Close the bookmarks drawer and reload the bookmarks list view when returning to the main WebView activity.
MainWebViewActivity.restartFromBookmarksActivity = true
private fun loadFolder() {
// Update the bookmarks cursor with the contents of the bookmarks database for the current folder.
- bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder)
+ bookmarksCursor = if (sortBookmarksAlphabetically)
+ bookmarksDatabaseHelper.getBookmarksSortedAlphabetically(currentFolderId)
+ else
+ bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderId)
// Setup a cursor adapter.
bookmarksCursorAdapter = object : CursorAdapter(this, bookmarksCursor, false) {
val bookmarkNameTextView = view.findViewById<TextView>(R.id.bookmark_name)
// Get the favorite icon byte array from the cursor.
- val favoriteIconByteArray = cursor.getBlob(cursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.FAVORITE_ICON))
+ val favoriteIconByteArray = cursor.getBlob(cursor.getColumnIndexOrThrow(FAVORITE_ICON))
// Convert the byte array to a bitmap beginning at the first byte and ending at the last.
val favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.size)
bookmarkFavoriteIconImageView.setImageBitmap(favoriteIconBitmap)
// Get the bookmark name from the cursor.
- val bookmarkNameString = cursor.getString(cursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.BOOKMARK_NAME))
+ val bookmarkNameString = cursor.getString(cursor.getColumnIndexOrThrow(BOOKMARK_NAME))
// Display the bookmark name.
bookmarkNameTextView.text = bookmarkNameString
// Make the font bold for folders.
- if (cursor.getInt(cursor.getColumnIndexOrThrow(BookmarksDatabaseHelper.IS_FOLDER)) == 1)
+ if (cursor.getInt(cursor.getColumnIndexOrThrow(IS_FOLDER)) == 1)
bookmarkNameTextView.typeface = Typeface.DEFAULT_BOLD
else // Reset the font to default for normal bookmarks.
bookmarkNameTextView.typeface = Typeface.DEFAULT
bookmarksListView.adapter = bookmarksCursorAdapter
// Set the app bar title.
- if (currentFolder.isEmpty())
+ if (currentFolderId == HOME_FOLDER_ID) // The home folder is the current folder.
appBar.setTitle(R.string.bookmarks)
else
- appBar.title = currentFolder
+ appBar.title = bookmarksDatabaseHelper.getFolderName(currentFolderId)
}
public override fun onDestroy() {