From: Soren Stoutner <soren@stoutner.com> Date: Fri, 18 Jan 2019 23:11:06 +0000 (-0700) Subject: Add a context menu to delete bookmarks from the database view activity. https:/... X-Git-Tag: v2.16~6 X-Git-Url: https://gitweb.stoutner.com/?a=commitdiff_plain;h=572449f6c66adfc1a3d88e761cb87581a7961df3;p=PrivacyBrowserAndroid.git Add a context menu to delete bookmarks from the database view activity. https://redmine.stoutner.com/issues/220 --- 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 e6c993ab..576e6532 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java @@ -65,7 +65,7 @@ import java.io.ByteArrayOutputStream; public class BookmarksActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, EditBookmarkDialog.EditBookmarkListener, EditBookmarkFolderDialog.EditBookmarkFolderListener, MoveToFolderDialog.MoveToFolderListener { - // `currentFolder` is public static so it can be accessed from `MoveToFolderDialog`. + // `currentFolder` is public static so it can be accessed from `MoveToFolderDialog` and `BookmarksDatabaseViewActivity`. // It is used in `onCreate`, `onOptionsItemSelected()`, `onBackPressed()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveBookmark()`, `onSaveBookmarkFolder()`, `onMoveToFolder()`, // and `loadFolder()`. public static String currentFolder; @@ -74,6 +74,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // and `updateMoveIcons()`. public static long[] checkedItemIds; + // `restartFromBookmarksDatabaseViewActivity` is public static so it can be accessed from `BookmarksDatabaseViewActivity`. It is also used in `onRestart()`. + public static boolean restartFromBookmarksDatabaseViewActivity; + // `bookmarksDatabaseHelper` is used in `onCreate()`, `onOptionsItemSelected()`, `onBackPressed()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveBookmark()`, `onSaveBookmarkFolder()`, // `onMoveToFolder()`, `deleteBookmarkFolderContents()`, `loadFolder()`, and `onDestroy()`. @@ -169,7 +172,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma int databaseID = (int) id; // Get the bookmark cursor for this ID and move it to the first row. - Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmarkCursor(databaseID); + Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmark(databaseID); bookmarkCursor.moveToFirst(); // Act upon the bookmark according to the type. @@ -203,7 +206,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Get a handle for the activity. Activity activity = this; - // `MultiChoiceModeListener` handles long clicks. + // Handle long presses on the list view. bookmarksListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { // Instantiate the common variables. MenuItem editBookmarkMenuItem; @@ -213,18 +216,17 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { - // Inflate the menu for the contextual app bar and set the title. + // Inflate the menu for the contextual app bar. getMenuInflater().inflate(R.menu.bookmarks_context_menu, menu); // Set the title. - if (currentFolder.isEmpty()) { - // Use `R.string.bookmarks` if we are in the home folder. + if (currentFolder.isEmpty()) { // Use `R.string.bookmarks` if in the home folder. mode.setTitle(R.string.bookmarks); } else { // Use the current folder name as the title. mode.setTitle(currentFolder); } - // Get a handle for `MenuItems` that need to be selectively disabled. + // 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); editBookmarkMenuItem = menu.findItem(R.id.edit_bookmark); @@ -232,11 +234,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma selectAllBookmarksMenuItem = menu.findItem(R.id.context_menu_select_all_bookmarks); // Disable the delete bookmarks menu item if a delete is pending. - if (deletingBookmarks) { - deleteBookmarksMenuItem.setEnabled(false); - } + deleteBookmarksMenuItem.setEnabled(!deletingBookmarks); - // Store `contextualActionMode` so it can be closed programatically. + // Store a handle for the contextual action mode so it can be closed programatically. contextualActionMode = mode; // Make it so. @@ -248,8 +248,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Get a handle for the move to folder menu item. MenuItem moveToFolderMenuItem = menu.findItem(R.id.move_to_folder); - // Get a `Cursor` with all of the folders. - Cursor folderCursor = bookmarksDatabaseHelper.getAllFoldersCursor(); + // Get a Cursor with all of the folders. + Cursor folderCursor = bookmarksDatabaseHelper.getAllFolders(); // Enable the move to folder menu item if at least one folder exists. moveToFolderMenuItem.setVisible(folderCursor.getCount() > 0); @@ -260,17 +260,11 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { - // Get a long array of the selected bookmarks. - long[] selectedBookmarksLongArray = bookmarksListView.getCheckedItemIds(); - - // Calculate the number of selected bookmarks. - int numberOfSelectedBookmarks = selectedBookmarksLongArray.length; + // Get the number of selected bookmarks. + int numberOfSelectedBookmarks = bookmarksListView.getCheckedItemCount(); - // Adjust the `ActionMode` and the `Menu` according to the number of selected bookmarks. - if (numberOfSelectedBookmarks == 0) { // No bookmarks are selected. - // Close the `ActionMode`. - mode.finish(); - } else if (numberOfSelectedBookmarks == 1) { // One bookmark is selected. + // Adjust the ActionMode and the menu according to the number of selected bookmarks. + if (numberOfSelectedBookmarks == 1) { // One bookmark is selected. // List the number of selected bookmarks in the subtitle. mode.setSubtitle(getString(R.string.selected) + " 1"); @@ -291,8 +285,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma editBookmarkMenuItem.setVisible(false); } - // Do not show `Select All` if all the bookmarks are already checked. - if (bookmarksListView.getCheckedItemIds().length == bookmarksListView.getCount()) { + // Do not show the select all menu item if all the bookmarks are already checked. + if (bookmarksListView.getCheckedItemCount() == bookmarksListView.getCount()) { selectAllBookmarksMenuItem.setVisible(false); } else { selectAllBookmarksMenuItem.setVisible(true); @@ -301,15 +295,12 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - // Get the menu item ID. - int menuItemId = item.getItemId(); - // Instantiate the common variables. int selectedBookmarkPosition; int selectedBookmarkNewPosition; final SparseBooleanArray selectedBookmarksPositionsSparseBooleanArray; - switch (menuItemId) { + switch (item.getItemId()) { case R.id.move_bookmark_up: // Get the array of checked bookmark positions. selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.getCheckedItemPositions(); @@ -343,8 +334,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } } - // Update `bookmarksCursor` with the current contents of the bookmarks database. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the current contents of the bookmarks database. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -389,8 +380,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } } - // Update `bookmarksCursor` with the current contents of the bookmarks database. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the current contents of the bookmarks database. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -447,18 +438,19 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Get an array of the selected row IDs. final long[] selectedBookmarksIdsLongArray = bookmarksListView.getCheckedItemIds(); - // 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. + // 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.getCheckedItemPositions().clone(); - // Update `bookmarksCursor` with the current contents of the bookmarks database except for the specified database IDs. - bookmarksCursor = bookmarksDatabaseHelper.getBookmarksCursorExcept(selectedBookmarksIdsLongArray, currentFolder); + // Update the bookmarks cursor with the current contents of the bookmarks database except for the specified database IDs. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrderExcept(selectedBookmarksIdsLongArray, currentFolder); - // Update the `ListView`. + // Update the list view. bookmarksCursorAdapter.changeCursor(bookmarksCursor); // Show a Snackbar with the number of deleted bookmarks. bookmarksDeletedSnackbar = Snackbar.make(findViewById(R.id.bookmarks_coordinatorlayout), getString(R.string.bookmarks_deleted) + " " + selectedBookmarksIdsLongArray.length, - Snackbar.LENGTH_LONG).setAction(R.string.undo, view -> { + Snackbar.LENGTH_LONG) + .setAction(R.string.undo, view -> { // Do nothing because everything will be handled by `onDismissed()` below. }) .addCallback(new Snackbar.Callback() { @@ -467,20 +459,19 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma switch (event) { // The user pushed the `Undo` button. case Snackbar.Callback.DISMISS_EVENT_ACTION: - // Update `bookmarksCursor` with the current contents of the bookmarks database, including the "deleted" bookmarks. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the current contents of the bookmarks database, including the "deleted" bookmarks. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); - // Update the `ListView`. + // Update the list view. bookmarksCursorAdapter.changeCursor(bookmarksCursor); // Re-select the previously selected bookmarks. for (int i = 0; i < selectedBookmarksPositionsSparseBooleanArray.size(); i++) { bookmarksListView.setItemChecked(selectedBookmarksPositionsSparseBooleanArray.keyAt(i), true); } - break; - // The `Snackbar` was dismissed without the `Undo` button being pushed. + // The Snackbar was dismissed without the `Undo` button being pushed. default: // Delete each selected bookmark. for (long databaseIdLong : selectedBookmarksIdsLongArray) { @@ -511,31 +502,21 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } } - // Enable the delete bookmarks menu item. - deleteBookmarksMenuItem.setEnabled(true); - // Reset the deleting bookmarks flag. deletingBookmarks = false; + // Enable the delete bookmarks menu item. + deleteBookmarksMenuItem.setEnabled(true); + // Close the activity if back has been pressed. if (closeActivityAfterDismissingSnackbar) { - // Update the bookmarks folder for the bookmarks drawer in the main WebView activity. - MainWebViewActivity.currentBookmarksFolder = currentFolder; - - // Close the bookmarks drawer and reload the bookmarks ListView when returning to the main WebView activity. - MainWebViewActivity.restartFromBookmarksActivity = true; - - // Return to `MainWebViewActivity`. - NavUtils.navigateUpFromSameTask(activity); + onBackPressed(); } } }); - //Show the `SnackBar`. + //Show the Snackbar. bookmarksDeletedSnackbar.show(); - - // Close the `ActionBar`. - mode.finish(); break; case R.id.context_menu_select_all_bookmarks: @@ -578,6 +559,21 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma }); } + @Override + public void onRestart() { + // Run the default commands. + super.onRestart(); + + // Update the list view if returning from the bookmarks database view activity. + if (restartFromBookmarksDatabaseViewActivity) { + // Load the current folder in the list view. + loadFolder(); + + // Reset `restartFromBookmarksDatabaseViewActivity`. + restartFromBookmarksDatabaseViewActivity = false; + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu. @@ -589,32 +585,14 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public boolean onOptionsItemSelected(MenuItem menuItem) { - // Get the ID of the menu item that was selected. - int menuItemId = menuItem.getItemId(); - - switch (menuItemId) { + switch (menuItem.getItemId()) { case android.R.id.home: // The home arrow is identified as `android.R.id.home`, not just `R.id.home`. if (currentFolder.isEmpty()) { // Currently in the home folder. - // Go home. - if ((bookmarksDeletedSnackbar != null) && bookmarksDeletedSnackbar.isShown()) { // Close the bookmarks delete snackbar before going home. - // Set the close flag. - closeActivityAfterDismissingSnackbar = true; - - // Dismiss the snackbar. - bookmarksDeletedSnackbar.dismiss(); - } else { // Go home immediately. - // Update the bookmarks folder for the bookmarks drawer in `MainWebViewActivity`. - MainWebViewActivity.currentBookmarksFolder = ""; - - // Close the bookmarks drawer and reload the bookmarks `ListView` when returning to `MainWebViewActivity`. - MainWebViewActivity.restartFromBookmarksActivity = true; - - // Return to `MainWebViewActivity`. - NavUtils.navigateUpFromSameTask(this); - } + // Run the back commands. + onBackPressed(); } else { // Currently in a subfolder. // Place the former parent folder in `currentFolder`. - currentFolder = bookmarksDatabaseHelper.getParentFolder(currentFolder); + currentFolder = bookmarksDatabaseHelper.getParentFolderName(currentFolder); // Load the new folder. loadFolder(); @@ -642,8 +620,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public void onBackPressed() { - // Check to see if a snackbar is currently displayed. If so, it must be closed before exiting so that a pending delete is completed before reloading the ListView in the bookmarks drawer. - if ((bookmarksDeletedSnackbar != null) && bookmarksDeletedSnackbar.isShown()) { // Close the bookmarks delete snackbar before going home. + // Check to see if a snackbar is currently displayed. If so, it must be closed before exiting so that a pending delete is completed before reloading the list view in the bookmarks drawer. + if ((bookmarksDeletedSnackbar != null) && bookmarksDeletedSnackbar.isShown()) { // Close the bookmarks deleted snackbar before going home. // Set the close flag. closeActivityAfterDismissingSnackbar = true; @@ -656,7 +634,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Close the bookmarks drawer and reload the bookmarks ListView when returning to the main WebView activity. MainWebViewActivity.restartFromBookmarksActivity = true; - // Exit `BookmarksActivity`. + // Exit the bookmarks activity. super.onBackPressed(); } } @@ -682,8 +660,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Create the bookmark. bookmarksDatabaseHelper.createBookmark(bookmarkNameString, bookmarkUrlString, currentFolder, newBookmarkDisplayOrder, favoriteIconByteArray); - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -727,8 +705,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Create the folder, which will be placed at the top of the `ListView`. bookmarksDatabaseHelper.createFolder(folderNameString, currentFolder, folderIconByteArray); - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -764,8 +742,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Close the contextual action mode. contextualActionMode.finish(); - // Update `bookmarksCursor` with the contents of the current folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the contents of the current folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -828,8 +806,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString, folderIconByteArray); } - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -873,8 +851,8 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma bookmarksDatabaseHelper.moveToFolder(databaseIdInt, newFolderName); } - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -888,7 +866,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma String folderName = bookmarksDatabaseHelper.getFolderName(databaseId); // Get the contents of the folder. - Cursor folderCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(folderName); + Cursor folderCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(folderName); // Delete each of the bookmarks in the folder. for (int i = 0; i < folderCursor.getCount(); i++) { @@ -969,15 +947,16 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma if (selectedBookmarkPosition <= firstVisibleBookmarkPosition) { // The selected bookmark position is at or above the top of the screen. // Scroll to the selected bookmark position. bookmarksListView.setSelection(selectedBookmarkPosition); - } else if (selectedBookmarkPosition >= (lastVisibleBookmarkPosition - 1)) { // The selected bookmark is at or below the bottom of the screen. The `-1` handles partial bookmarks displayed at the bottom of the `ListView`. - // Scroll to display the selected bookmark at the bottom of the screen. `+1` assured that the entire bookmark will be displayed in situations where only a partial bookmark fits at the bottom of the `ListView`. + } else if (selectedBookmarkPosition >= (lastVisibleBookmarkPosition - 1)) { // The selected bookmark is at or below the bottom of the screen. + // The `-1` handles partial bookmarks displayed at the bottom of the list view. This command scrolls to display the selected bookmark at the bottom of the screen. + // `+1` assures that the entire bookmark will be displayed in situations where only a partial bookmark fits at the bottom of the list view. bookmarksListView.setSelection(selectedBookmarkPosition - numberOfBookmarksPerScreen + 1); } } private void loadFolder() { - // Update `bookmarksCursor` with the contents of the bookmarks database for the current folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolder); + // Update bookmarks cursor with the contents of the bookmarks database for the current folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolder); // Setup a `CursorAdapter`. `this` specifies the `Context`. `false` disables `autoRequery`. bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) { @@ -1015,7 +994,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } }; - // Populate the `ListView` with the adapter. + // Populate the list view with the adapter. bookmarksListView.setAdapter(bookmarksCursorAdapter); // Set the `AppBar` title. diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java index 1f011f72..dd9c42cf 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java @@ -30,7 +30,6 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; 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.v4.widget.ResourceCursorAdapter; @@ -39,11 +38,14 @@ import android.support.v7.app.AppCompatActivity; // `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22. import android.support.v7.app.AppCompatDialogFragment; import android.support.v7.widget.Toolbar; +import android.util.SparseBooleanArray; +import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ImageView; @@ -59,18 +61,19 @@ import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper; import java.io.ByteArrayOutputStream; -public class BookmarksDatabaseViewActivity extends AppCompatActivity implements EditBookmarkDatabaseViewDialog.EditBookmarkDatabaseViewListener, EditBookmarkFolderDatabaseViewDialog.EditBookmarkFolderDatabaseViewListener { +public class BookmarksDatabaseViewActivity extends AppCompatActivity implements EditBookmarkDatabaseViewDialog.EditBookmarkDatabaseViewListener, + EditBookmarkFolderDatabaseViewDialog.EditBookmarkFolderDatabaseViewListener { // Instantiate the constants. private static final int ALL_FOLDERS_DATABASE_ID = -2; private static final int HOME_FOLDER_DATABASE_ID = -1; - // `bookmarksDatabaseHelper` is used in `onCreate()`, `updateBookmarksListView()`, and `onDestroy()`. + // `bookmarksDatabaseHelper` is used in `onCreate()`, `updateBookmarksListView()`, `selectAllBookmarksInFolder()`, and `onDestroy()`. private BookmarksDatabaseHelper bookmarksDatabaseHelper; // `bookmarksCursor` is used in `onCreate()`, `updateBookmarksListView()`, `onSaveBookmark()`, `onSaveBookmarkFolder()`, and `onDestroy()`. private Cursor bookmarksCursor; - // `bookmarksCursorAdapter` is used in `onCreate()` and `updateBookmarksListView()`. + // `bookmarksCursorAdapter` is used in `onCreate()`, `selectAllBookmarksInFolder()`, and `updateBookmarksListView()`. private CursorAdapter bookmarksCursorAdapter; // `oldFolderNameString` is used in `onCreate()` and `onSaveBookmarkFolder()`. @@ -85,6 +88,12 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements // `sortByDisplayOrder` is used in `onCreate()`, `onOptionsItemSelected()`, and `updateBookmarksListView()`. private boolean sortByDisplayOrder; + // `bookmarksDeletedSnackbar` is used in `onCreate()`, `onOptionsItemSelected()`, and `onBackPressed()`. + private Snackbar bookmarksDeletedSnackbar; + + // `closeActivityAfterDismissingSnackbar` is used in `onCreate()`, `onOptionsItemSelected()`, and `onBackPressed()`. + private boolean closeActivityAfterDismissingSnackbar; + @Override public void onCreate(Bundle savedInstanceState) { // Disable screenshots if not allowed. @@ -119,7 +128,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements appBar.setCustomView(R.layout.spinner); appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP); - // Initialize the database handler. `this` specifies the context. The two `null`s do not specify the database name or a `CursorFactory`. The `0` is to specify a database version, but that is set instead using a constant in `BookmarksDatabaseHelper`. + // Initialize the database handler. `this` specifies the context. The `0` is to specify a database version, but that is set instead using a constant in `BookmarksDatabaseHelper`. bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this, null, null, 0); // Setup a matrix cursor for "All Folders" and "Home Folder". @@ -128,8 +137,8 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements matrixCursor.addRow(new Object[]{ALL_FOLDERS_DATABASE_ID, getString(R.string.all_folders)}); matrixCursor.addRow(new Object[]{HOME_FOLDER_DATABASE_ID, getString(R.string.home_folder)}); - // Get a `Cursor` with the list of all the folders. - Cursor foldersCursor = bookmarksDatabaseHelper.getAllFoldersCursor(); + // Get a cursor with the list of all the folders. + Cursor foldersCursor = bookmarksDatabaseHelper.getAllFolders(); // Combine `matrixCursor` and `foldersCursor`. MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{matrixCursor, foldersCursor}); @@ -153,7 +162,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements Spinner folderSpinner = findViewById(R.id.spinner); folderSpinner.setAdapter(foldersCursorAdapter); - // Handle clicks on the spinner dropdown. + // Handle taps on the spinner dropdown. folderSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { @@ -180,7 +189,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements ListView bookmarksListView = findViewById(R.id.bookmarks_databaseview_listview); // Get a `Cursor` with the current contents of the bookmarks database. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursor(); + bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarks(); // Setup a `CursorAdapter` with `this` context. `false` disables autoRequery. bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) { @@ -269,7 +278,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements // Set a listener to edit a bookmark when it is tapped. bookmarksListView.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id) -> { - // Convert the database ID to an `int`. + // Convert the database ID to an int. int databaseId = (int) id; // Show the edit bookmark or edit bookmark folder dialog. @@ -286,6 +295,218 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements editBookmarkDatabaseViewDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_bookmark)); } }); + + // Handle long presses on the list view. + bookmarksListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { + // Instantiate the common variables. + MenuItem selectAllMenuItem; + MenuItem deleteMenuItem; + boolean deletingBookmarks; + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + // Inflate the menu for the contextual app bar. + getMenuInflater().inflate(R.menu.bookmarks_databaseview_context_menu, menu); + + // Set the title. + mode.setTitle(R.string.bookmarks); + + // Get handles for the menu items. + selectAllMenuItem = menu.findItem(R.id.select_all); + deleteMenuItem = menu.findItem(R.id.delete); + + // Disable the delete menu item if a delete is pending. + deleteMenuItem.setEnabled(!deletingBookmarks); + + // Make it so. + return true; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + // Do nothing. + return false; + } + + @Override + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { + // Calculate the number of selected bookmarks. + int numberOfSelectedBookmarks = bookmarksListView.getCheckedItemCount(); + + // Adjust the ActionMode according to the number of selected bookmarks. + mode.setSubtitle(getString(R.string.selected) + " " + numberOfSelectedBookmarks); + + // Do not show the select all menu item if all the bookmarks are already checked. + if (bookmarksListView.getCheckedItemCount() == bookmarksListView.getCount()) { + selectAllMenuItem.setVisible(false); + } else { + selectAllMenuItem.setVisible(true); + } + + // Convert the database ID to an int. + int databaseId = (int) id; + + // If a folder was selected, also select all the contents. + if (checked && bookmarksDatabaseHelper.isFolder(databaseId)) { + selectAllBookmarksInFolder(databaseId); + } + + // Do not allow a bookmark to be deselected if the folder is selected. + if (!checked) { + // Get the folder name. + String folderName = bookmarksDatabaseHelper.getParentFolderName((int) id); + + // If the bookmark is not in the root folder, check to see if the folder is selected. + if (!folderName.isEmpty()) { + // Get the database ID of the folder. + int folderDatabaseId = bookmarksDatabaseHelper.getFolderDatabaseId(folderName); + + // Move the bookmarks cursor to the first position. + bookmarksCursor.moveToFirst(); + + // Initialize the folder position variable. + int folderPosition = -1; + + // Get the position of the folder in the bookmarks cursor. + while ((folderPosition < 0) && (bookmarksCursor.getPosition() < bookmarksCursor.getCount())) { + // Check if the folder database ID matches the bookmark database ID. + if (folderDatabaseId == bookmarksCursor.getInt((bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper._ID)))) { + // Get the folder position. + folderPosition = bookmarksCursor.getPosition(); + + // Check if the folder is selected. + if (bookmarksListView.isItemChecked(folderPosition)) { + // Reselect the bookmark. + bookmarksListView.setItemChecked(position, true); + + // Display a snackbar explaining why the bookmark cannot be deselected. + Snackbar.make(bookmarksListView, R.string.cannot_deselect_bookmark, Snackbar.LENGTH_LONG).show(); + } + } + + // Increment the bookmarks cursor. + bookmarksCursor.moveToNext(); + } + } + } + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + switch (item.getItemId()) { + case R.id.select_all: + // Get the total number of bookmarks. + int numberOfBookmarks = bookmarksListView.getCount(); + + // Select them all. + for (int i = 0; i < numberOfBookmarks; i++) { + bookmarksListView.setItemChecked(i, true); + } + break; + + case R.id.delete: + // 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. + long[] selectedBookmarksIdsLongArray = bookmarksListView.getCheckedItemIds(); + + // 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. + SparseBooleanArray selectedBookmarksPositionsSparseBooleanArray = bookmarksListView.getCheckedItemPositions().clone(); + + // Update the bookmarks cursor with the current contents of the bookmarks database except for the specified database IDs. + switch (currentFolderDatabaseId) { + // Get a cursor with all the folders. + case ALL_FOLDERS_DATABASE_ID: + if (sortByDisplayOrder) { + bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksByDisplayOrderExcept(selectedBookmarksIdsLongArray); + } else { + bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksExcept(selectedBookmarksIdsLongArray); + } + break; + + // Get a cursor for the home folder. + case HOME_FOLDER_DATABASE_ID: + if (sortByDisplayOrder) { + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrderExcept(selectedBookmarksIdsLongArray, ""); + } else { + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksExcept(selectedBookmarksIdsLongArray, ""); + } + break; + + // Display the selected folder. + default: + // Get a cursor for the selected folder. + if (sortByDisplayOrder) { + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrderExcept(selectedBookmarksIdsLongArray, currentFolderName); + } else { + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksExcept(selectedBookmarksIdsLongArray, currentFolderName); + } + } + + // Update the list view. + bookmarksCursorAdapter.changeCursor(bookmarksCursor); + + // Show a Snackbar with the number of deleted bookmarks. + bookmarksDeletedSnackbar = Snackbar.make(findViewById(R.id.bookmarks_databaseview_coordinatorlayout), + getString(R.string.bookmarks_deleted) + " " + selectedBookmarksIdsLongArray.length, Snackbar.LENGTH_LONG) + .setAction(R.string.undo, view -> { + // Do nothing because everything will be handled by `onDismissed()` below. + }) + .addCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + switch (event) { + // The user pushed the `Undo` button. + case Snackbar.Callback.DISMISS_EVENT_ACTION: + // Update the bookmarks list view with the current contents of the bookmarks database, including the "deleted bookmarks. + updateBookmarksListView(); + + // Re-select the previously selected bookmarks. + for (int i = 0; i < selectedBookmarksPositionsSparseBooleanArray.size(); i++) { + bookmarksListView.setItemChecked(selectedBookmarksPositionsSparseBooleanArray.keyAt(i), true); + } + break; + + // The Snackbar was dismissed without the `Undo` button being pushed. + default: + // Delete each selected bookmark. + for (long databaseIdLong : selectedBookmarksIdsLongArray) { + // Convert `databaseIdLong` to an int. + int databaseIdInt = (int) databaseIdLong; + + // Delete the selected bookmark. + bookmarksDatabaseHelper.deleteBookmark(databaseIdInt); + } + } + + // Reset the deleting bookmarks flag. + deletingBookmarks = false; + + // Enable the delete menu item. + deleteMenuItem.setEnabled(true); + + // Close the activity if back has been pressed. + if (closeActivityAfterDismissingSnackbar) { + onBackPressed(); + } + } + }); + + // Show the Snackbar. + bookmarksDeletedSnackbar.show(); + break; + } + + // Consume the click. + return false; + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + // Do nothing. + } + }); } @Override @@ -304,8 +525,8 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements switch (menuItemId) { case android.R.id.home: // The home arrow is identified as `android.R.id.home`, not just `R.id.home`. - // Return to `MainWebViewActivity`. - NavUtils.navigateUpFromSameTask(this); + // Exit the activity. + onBackPressed(); break; case R.id.options_menu_sort: @@ -345,24 +566,59 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements return true; } + @Override + public void onBackPressed() { + // Check to see if a snackbar is currently displayed. If so, it must be closed before existing so that a pending delete is completed before reloading the list view in the bookmarks activity. + if ((bookmarksDeletedSnackbar != null) && bookmarksDeletedSnackbar.isShown()) { // Close the bookmarks deleted snackbar before going home. + // Set the close flag. + closeActivityAfterDismissingSnackbar = true; + + // Dismiss the snackbar. + bookmarksDeletedSnackbar.dismiss(); + } else { // Go home immediately. + // Update the current folder in the bookmarks activity. + switch (currentFolderDatabaseId) { + case ALL_FOLDERS_DATABASE_ID: + // Load the home folder. + BookmarksActivity.currentFolder = ""; + break; + + case HOME_FOLDER_DATABASE_ID: + // Load the home folder. + BookmarksActivity.currentFolder = ""; + break; + + default: + // Load the current folder. + BookmarksActivity.currentFolder = currentFolderName; + } + + // Reload the bookmarks list view when returning to the bookmarks activity. + BookmarksActivity.restartFromBookmarksDatabaseViewActivity = true; + + // Exit the bookmarks database view activity. + super.onBackPressed(); + } + } + private void updateBookmarksListView() { // Populate the bookmarks list view based on the spinner selection. switch (currentFolderDatabaseId) { // Get a cursor with all the folders. case ALL_FOLDERS_DATABASE_ID: if (sortByDisplayOrder) { - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(); + bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksByDisplayOrder(); } else { - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursor(); + bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarks(); } break; // Get a cursor for the home folder. case HOME_FOLDER_DATABASE_ID: if (sortByDisplayOrder) { - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(""); + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(""); } else { - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursor(""); + bookmarksCursor = bookmarksDatabaseHelper.getBookmarks(""); } break; @@ -370,9 +626,9 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements default: // Get a cursor for the selected folder. if (sortByDisplayOrder) { - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentFolderName); + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentFolderName); } else { - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursor(currentFolderName); + bookmarksCursor = bookmarksDatabaseHelper.getBookmarks(currentFolderName); } } @@ -380,6 +636,54 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements bookmarksCursorAdapter.changeCursor(bookmarksCursor); } + private void selectAllBookmarksInFolder(int folderId) { + // Get a handle for the bookmarks list view. + ListView bookmarksListView = findViewById(R.id.bookmarks_databaseview_listview); + + // Get the folder name. + String folderName = bookmarksDatabaseHelper.getFolderName(folderId); + + // Get a cursor with the contents of the folder. + Cursor folderCursor = bookmarksDatabaseHelper.getBookmarks(folderName); + + // Move to the beginning of the cursor. + folderCursor.moveToFirst(); + + while (folderCursor.getPosition() < folderCursor.getCount()) { + // Get the bookmark database ID. + int bookmarkId = folderCursor.getInt(folderCursor.getColumnIndex(BookmarksDatabaseHelper._ID)); + + // Move the bookmarks cursor to the first position. + bookmarksCursor.moveToFirst(); + + // Initialize the bookmark position variable. + int bookmarkPosition = -1; + + // Get the position of this bookmark in the bookmarks cursor. + while ((bookmarkPosition < 0) && (bookmarksCursor.getPosition() < bookmarksCursor.getCount())) { + // Check if the bookmark IDs match. + if (bookmarkId == bookmarksCursor.getInt(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper._ID))) { + // Get the bookmark position. + bookmarkPosition = bookmarksCursor.getPosition(); + + // If this bookmark is a folder, select all the bookmarks inside it. + if (bookmarksDatabaseHelper.isFolder(bookmarkId)) { + selectAllBookmarksInFolder(bookmarkId); + } + + // Select the bookmark. + bookmarksListView.setItemChecked(bookmarkPosition, true); + } + + // Increment the bookmarks cursor position. + bookmarksCursor.moveToNext(); + } + + // Move to the next position. + folderCursor.moveToNext(); + } + } + @Override public void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) { // Get handles for the views from dialog fragment. diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 647cdb71..c1463d92 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -769,7 +769,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Update `findOnPageCountTextView`. mainWebView.setFindListener(new WebView.FindListener() { // Get a handle for `findOnPageCountTextView`. - final TextView findOnPageCountTextView = (TextView) findViewById(R.id.find_on_page_count_textview); + final TextView findOnPageCountTextView = findViewById(R.id.find_on_page_count_textview); @Override public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting) { @@ -863,7 +863,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook int databaseID = (int) id; // Get the bookmark cursor for this ID and move it to the first row. - Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmarkCursor(databaseID); + Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmark(databaseID); bookmarkCursor.moveToFirst(); // Act upon the bookmark according to the type. @@ -3488,8 +3488,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Create the bookmark. bookmarksDatabaseHelper.createBookmark(bookmarkNameString, bookmarkUrlString, currentBookmarksFolder, newBookmarkDisplayOrder, favoriteIconByteArray); - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3533,8 +3533,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Create the folder, which will be placed at the top of the `ListView`. bookmarksDatabaseHelper.createFolder(folderNameString, currentBookmarksFolder, folderIconByteArray); - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3748,8 +3748,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook bookmarksDatabaseHelper.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString, newFavoriteIconByteArray); } - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3810,8 +3810,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, oldFolderNameString, newFolderNameString, folderIconByteArray); } - // Update `bookmarksCursor` with the current contents of this folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + // Update the bookmarks cursor with the current contents of this folder. + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Update the `ListView`. bookmarksCursorAdapter.changeCursor(bookmarksCursor); @@ -3902,7 +3902,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook drawerLayout.closeDrawer(GravityCompat.END); } else { // A subfolder is displayed. // Place the former parent folder in `currentFolder`. - currentBookmarksFolder = bookmarksDatabaseHelper.getParentFolder(currentBookmarksFolder); + currentBookmarksFolder = bookmarksDatabaseHelper.getParentFolderName(currentBookmarksFolder); // Load the new folder. loadBookmarksFolder(); @@ -4745,7 +4745,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook private void loadBookmarksFolder() { // Update the bookmarks cursor with the contents of the bookmarks database for the current folder. - bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursorByDisplayOrder(currentBookmarksFolder); + bookmarksCursor = bookmarksDatabaseHelper.getBookmarksByDisplayOrder(currentBookmarksFolder); // Populate the bookmarks cursor adapter. `this` specifies the `Context`. `false` disables `autoRequery`. bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java index 670d237b..a7a96616 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>. + * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. * @@ -140,7 +140,7 @@ public class CreateBookmarkFolderDialog extends AppCompatDialogFragment { String folderName = s.toString(); // Check if a folder with the name already exists. - Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolderCursor(folderName); + Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolder(folderName); // Enable the create button if the new folder name is not empty and doesn't already exist. createButton.setEnabled(!folderName.isEmpty() && (folderExistsCursor.getCount() == 0)); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java index 272e4719..7328080e 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>. + * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. * @@ -115,7 +115,7 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment { BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0); // Get a cursor with the selected bookmark and move it to the first position. - Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmarkCursor(bookmarkDatabaseId); + Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmark(bookmarkDatabaseId); bookmarkCursor.moveToFirst(); // Use an alert dialog builder to create the alert dialog. @@ -207,7 +207,7 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment { matrixCursor.addRow(new Object[]{HOME_FOLDER_DATABASE_ID, getString(R.string.home_folder)}); // Get a `Cursor` with the list of all the folders. - Cursor foldersCursor = bookmarksDatabaseHelper.getAllFoldersCursor(); + Cursor foldersCursor = bookmarksDatabaseHelper.getAllFolders(); // Combine `matrixCursor` and `foldersCursor`. MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{matrixCursor, foldersCursor}); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java index 27be599c..0bb5f9da 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>. + * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. * @@ -100,7 +100,7 @@ public class EditBookmarkDialog extends AppCompatDialogFragment { BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0); // Get a `Cursor` with the selected bookmark and move it to the first position. - Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmarkCursor(selectedBookmarkDatabaseId); + Cursor bookmarkCursor = bookmarksDatabaseHelper.getBookmark(selectedBookmarkDatabaseId); bookmarkCursor.moveToFirst(); // Use an alert dialog builder to create the alert dialog. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java index c2d44cd0..75e0d916 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>. + * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. * @@ -114,7 +114,7 @@ public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragmen bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0); // Get a `Cursor` with the selected bookmark and move it to the first position. - Cursor folderCursor = bookmarksDatabaseHelper.getBookmarkCursor(folderDatabaseId); + Cursor folderCursor = bookmarksDatabaseHelper.getBookmark(folderDatabaseId); folderCursor.moveToFirst(); // Use an alert dialog builder to create the alert dialog. @@ -210,7 +210,7 @@ public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragmen addSubfoldersToExceptFolders(currentFolderName); // Get a `Cursor` with the list of all the folders. - Cursor foldersCursor = bookmarksDatabaseHelper.getFoldersCursorExcept(exceptFolders.toString()); + Cursor foldersCursor = bookmarksDatabaseHelper.getFoldersExcept(exceptFolders.toString()); // Combine `matrixCursor` and `foldersCursor`. MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{matrixCursor, foldersCursor}); @@ -373,7 +373,7 @@ public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragmen String newDisplayOrder = displayOrderEditText.getText().toString(); // Get a cursor for the new folder name if it exists. - Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolderCursor(newFolderName); + Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolder(newFolderName); // Is the new folder name empty? boolean folderNameNotEmpty = !newFolderName.isEmpty(); @@ -402,7 +402,7 @@ public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragmen private void addSubfoldersToExceptFolders(String folderName) { // Get a `Cursor` will all the immediate subfolders. - Cursor subfoldersCursor = bookmarksDatabaseHelper.getSubfoldersCursor(folderName); + Cursor subfoldersCursor = bookmarksDatabaseHelper.getSubfolders(folderName); for (int i = 0; i < subfoldersCursor.getCount(); i++) { // Move `subfolderCursor` to the current item. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java index 0ef29c74..e854a065 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>. + * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. * @@ -94,7 +94,7 @@ public class EditBookmarkFolderDialog extends AppCompatDialogFragment { final BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0); // Get a `Cursor` with the selected folder and move it to the first position. - Cursor folderCursor = bookmarksDatabaseHelper.getBookmarkCursor(selectedFolderDatabaseId); + Cursor folderCursor = bookmarksDatabaseHelper.getBookmark(selectedFolderDatabaseId); folderCursor.moveToFirst(); // Use an alert dialog builder to create the alert dialog. @@ -189,7 +189,7 @@ public class EditBookmarkFolderDialog extends AppCompatDialogFragment { String newFolderName = s.toString(); // Get a cursor for the new folder name if it exists. - Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolderCursor(newFolderName); + Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolder(newFolderName); // Is the new folder name empty? boolean folderNameNotEmpty = !newFolderName.isEmpty(); @@ -214,7 +214,7 @@ public class EditBookmarkFolderDialog extends AppCompatDialogFragment { String newFolderName = folderNameEditText.getText().toString(); // Get a cursor for the new folder name if it exists. - Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolderCursor(newFolderName); + Cursor folderExistsCursor = bookmarksDatabaseHelper.getFolder(newFolderName); // Is the new folder name empty? boolean folderNameEmpty = newFolderName.isEmpty(); diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java index 2bbd4e66..51495344 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>. + * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. * @@ -166,12 +166,15 @@ public class MoveToFolderDialog extends AppCompatDialogFragment { } // Get a `Cursor` containing the folders to display. - foldersCursor = bookmarksDatabaseHelper.getFoldersCursorExcept(exceptFolders.toString()); + foldersCursor = bookmarksDatabaseHelper.getFoldersExcept(exceptFolders.toString()); // Setup `foldersCursorAdaptor` with `this` context. `false` disables autoRequery. foldersCursorAdapter = new CursorAdapter(alertDialog.getContext(), foldersCursor, false) { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { + // Remove the incorrect lint warning that `.getLayoutInflator()` might be false. + assert getActivity() != null; + // Inflate the individual item layout. `false` does not attach it to the root. return getActivity().getLayoutInflater().inflate(R.layout.move_to_folder_item_linearlayout, parent, false); } @@ -233,7 +236,7 @@ public class MoveToFolderDialog extends AppCompatDialogFragment { } // Get a `Cursor` containing the folders to display. - foldersCursor = bookmarksDatabaseHelper.getFoldersCursorExcept(exceptFolders.toString()); + foldersCursor = bookmarksDatabaseHelper.getFoldersExcept(exceptFolders.toString()); // Combine `homeFolderMatrixCursor` and `foldersCursor`. MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{homeFolderMatrixCursor, foldersCursor}); @@ -242,6 +245,9 @@ public class MoveToFolderDialog extends AppCompatDialogFragment { foldersCursorAdapter = new CursorAdapter(alertDialog.getContext(), foldersMergeCursor, false) { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { + // Remove the incorrect lint warning that `.getLayoutInflator()` might be false. + assert getActivity() != null; + // Inflate the individual item layout. `false` does not attach it to the root. return getActivity().getLayoutInflater().inflate(R.layout.move_to_folder_item_linearlayout, parent, false); } @@ -280,7 +286,7 @@ public class MoveToFolderDialog extends AppCompatDialogFragment { private void addSubfoldersToExceptFolders(String folderName) { // Get a `Cursor` will all the immediate subfolders. - Cursor subfoldersCursor = bookmarksDatabaseHelper.getSubfoldersCursor(folderName); + Cursor subfoldersCursor = bookmarksDatabaseHelper.getSubfolders(folderName); for (int i = 0; i < subfoldersCursor.getCount(); i++) { // Move `subfolderCursor` to the current item. diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java index ad97e38c..85089314 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java @@ -121,7 +121,7 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { } // Get a `Cursor` for the bookmark with the specified database ID. - public Cursor getBookmarkCursor(int databaseId) { + public Cursor getBookmark(int databaseId) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -157,7 +157,7 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { return folderName; } - // The the database ID for the specified folder name. + // Get the database ID for the specified folder name. public int getFolderDatabaseId (String folderName) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -185,8 +185,8 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { return databaseId; } - // Get a `Cursor` for the specified folder name. - public Cursor getFolderCursor(String folderName) { + // Get a cursor for the specified folder name. + public Cursor getFolder(String folderName) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -203,8 +203,8 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { return bookmarksDatabase.rawQuery(GET_FOLDER, null); } - // Get a `Cursor` of all the folders except those specified. - public Cursor getFoldersCursorExcept(String exceptFolders) { + // Get a cursor of all the folders except those specified. + public Cursor getFoldersExcept(String exceptFolders) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -219,8 +219,8 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { return bookmarksDatabase.rawQuery(GET_FOLDERS_EXCEPT, null); } - // Get a `Cursor` with all the subfolders of the specified folder. - public Cursor getSubfoldersCursor(String currentFolder) { + // Get a cursor with all the subfolders of the specified folder. + public Cursor getSubfolders(String currentFolder) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -237,34 +237,56 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { return bookmarksDatabase.rawQuery(GET_SUBFOLDERS, null); } - // Get a `String` with the name of the parent folder. - public String getParentFolder(String currentFolder) { + // Get the name of the parent folder. + public String getParentFolderName(String currentFolder) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); // SQL escape `currentFolder`. currentFolder = DatabaseUtils.sqlEscapeString(currentFolder); - // Prepare the SQL statement to get the parent folder. - String GET_PARENT_FOLDER = "SELECT * FROM " + BOOKMARKS_TABLE + + // Prepare the SQL statement to get the current folder. + String GET_CURRENT_FOLDER = "SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + IS_FOLDER + " = " + 1 + " AND " + BOOKMARK_NAME + " = " + currentFolder; // Get the bookmark cursor and move to the first entry. - Cursor bookmarkCursor = bookmarksDatabase.rawQuery(GET_PARENT_FOLDER, null); + Cursor bookmarkCursor = bookmarksDatabase.rawQuery(GET_CURRENT_FOLDER, null); bookmarkCursor.moveToFirst(); // Store the name of the parent folder. String parentFolder = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(PARENT_FOLDER)); - // Close the `Cursor`. + // Close the cursor. bookmarkCursor.close(); return parentFolder; } - // Get a `Cursor` of all the folders. - public Cursor getAllFoldersCursor() { + // Get the name of the parent folder. + public String getParentFolderName(int databaseId) { + // Get a readable database handle. + SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); + + // Prepare the SQL statement to get the current bookmark. + String GET_BOOKMARK = "SELECT * FROM " + BOOKMARKS_TABLE + + " WHERE " + _ID + " = " + databaseId; + + // Get the bookmark cursor and move to the first entry. + Cursor bookmarkCursor = bookmarksDatabase.rawQuery(GET_BOOKMARK, null); + bookmarkCursor.moveToFirst(); + + // Store the name of the parent folder. + String parentFolder = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(PARENT_FOLDER)); + + // Close the cursor. + bookmarkCursor.close(); + + return parentFolder; + } + + // Get a cursor of all the folders. + public Cursor getAllFolders() { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -279,7 +301,7 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { } // Get a cursor for all bookmarks and folders. - public Cursor getAllBookmarksCursor() { + public Cursor getAllBookmarks() { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -290,8 +312,74 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null); } - // Get a `Cursor` for all bookmarks and folders in the specified folder. - public Cursor getAllBookmarksCursor(String folderName) { + // Get a cursor for all bookmarks and folders ordered by display order. + public Cursor getAllBookmarksByDisplayOrder() { + // Get a readable database handle. + SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); + + // Get everything in the bookmarks table ordered by display order. + String GET_ALL_BOOKMARKS = "SELECT * FROM " + BOOKMARKS_TABLE + + " ORDER BY " + DISPLAY_ORDER + " ASC"; + + // Return the result as a cursor. The cursor cannot be closed because it is used in the parent activity. + return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null); + } + + // Get a cursor for all bookmarks and folders except those with the specified IDs. + public Cursor getAllBookmarksExcept(long[] exceptIdLongArray) { + // Get a readable database handle. + SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); + + // Prepare a string builder to contain the comma-separated list of IDs not to get. + StringBuilder idsNotToGetStringBuilder = new StringBuilder(); + + // Extract the array of IDs not to get to the string builder. + for (long databaseIdLong : exceptIdLongArray) { + if (idsNotToGetStringBuilder.length() == 0) { // This is the first number, so only add the number. + idsNotToGetStringBuilder.append(databaseIdLong); + } else { // This is not the first number, so place a `,` before the new number. + idsNotToGetStringBuilder.append(","); + idsNotToGetStringBuilder.append(databaseIdLong); + } + } + + // Prepare the SQL statement to select all items except those with the specified IDs. + String GET_ALL_BOOKMARKS_EXCEPT_SPECIFIED = "SELECT * FROM " + BOOKMARKS_TABLE + + " WHERE " + _ID + " NOT IN (" + idsNotToGetStringBuilder.toString() + ")"; + + // Return the results as a cursor. The cursor cannot be closed because it will be used in the parent activity. + return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS_EXCEPT_SPECIFIED, null); + } + + // Get a cursor for all bookmarks and folders by display order except for a specific of IDs. + public Cursor getAllBookmarksByDisplayOrderExcept(long[] exceptIdLongArray) { + // Get a readable database handle. + SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); + + // Prepare a string builder to contain the comma-separated list of IDs not to get. + StringBuilder idsNotToGetStringBuilder = new StringBuilder(); + + // Extract the array of IDs not to get to the string builder. + for (long databaseIdLong : exceptIdLongArray) { + if (idsNotToGetStringBuilder.length() == 0) { // This is the first number, so only add the number. + idsNotToGetStringBuilder.append(databaseIdLong); + } else { // This is not the first number, so place a `,` before the new number. + idsNotToGetStringBuilder.append(","); + idsNotToGetStringBuilder.append(databaseIdLong); + } + } + + // Prepare the SQL statement to select all items except those with the specified IDs. + String GET_ALL_BOOKMARKS_EXCEPT_SPECIFIED = "SELECT * FROM " + BOOKMARKS_TABLE + + " WHERE " + _ID + " NOT IN (" + idsNotToGetStringBuilder.toString() + + ") ORDER BY " + DISPLAY_ORDER + " ASC"; + + // Return the results as a cursor. The cursor cannot be closed because it will be used in the parent activity. + return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS_EXCEPT_SPECIFIED, null); + } + + // Get a cursor for bookmarks and folders in the specified folder. + public Cursor getBookmarks(String folderName) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); @@ -299,59 +387,75 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { folderName = DatabaseUtils.sqlEscapeString(folderName); // Get everything in the bookmarks table with `folderName` as the `PARENT_FOLDER`. - String GET_ALL_BOOKMARKS = "SELECT * FROM " + BOOKMARKS_TABLE + + String GET_BOOKMARKS = "SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER + " = " + folderName; // Return the result as a cursor. The cursor cannot be closed because it is used in the parent activity. - return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null); + return bookmarksDatabase.rawQuery(GET_BOOKMARKS, null); } - // Get a cursor for all bookmarks and folders ordered by display order. - public Cursor getAllBookmarksCursorByDisplayOrder() { + // Get a cursor for bookmarks and folders in the specified folder ordered by display order. + public Cursor getBookmarksByDisplayOrder(String folderName) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); - // Get everything in the bookmarks table ordered by display order. - String GET_ALL_BOOKMARKS = "SELECT * FROM " + BOOKMARKS_TABLE + + // SQL escape `folderName`. + folderName = DatabaseUtils.sqlEscapeString(folderName); + + // Get everything in the bookmarks table with `folderName` as the `PARENT_FOLDER`. + String GET_BOOKMARKS = "SELECT * FROM " + BOOKMARKS_TABLE + + " WHERE " + PARENT_FOLDER + " = " + folderName + " ORDER BY " + DISPLAY_ORDER + " ASC"; // Return the result as a cursor. The cursor cannot be closed because it is used in the parent activity. - return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null); + return bookmarksDatabase.rawQuery(GET_BOOKMARKS, null); } - // Get a cursor for all bookmarks and folders in the specified folder ordered by display order. - public Cursor getAllBookmarksCursorByDisplayOrder(String folderName) { + // Get a cursor for bookmarks and folders in the specified folder except for ta specific list of IDs. + public Cursor getBookmarksExcept(long[] exceptIdLongArray, String folderName) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); - // SQL escape `folderName`. + // Prepare a string builder to contain the comma-separated list of IDs not to get. + StringBuilder idsNotToGetStringBuilder = new StringBuilder(); + + // Extract the array of IDs not to get to the string builder. + for (long databaseIdLong : exceptIdLongArray) { + if (idsNotToGetStringBuilder.length() == 0) { // This is the first number, so only add the number. + idsNotToGetStringBuilder.append(databaseIdLong); + } else { // This is not the first number, so place a `,` before the new number. + idsNotToGetStringBuilder.append(","); + idsNotToGetStringBuilder.append(databaseIdLong); + } + } + + // SQL escape the folder name. folderName = DatabaseUtils.sqlEscapeString(folderName); - // Get everything in the bookmarks table with `folderName` as the `PARENT_FOLDER`. - String GET_ALL_BOOKMARKS = "SELECT * FROM " + BOOKMARKS_TABLE + + // Get everything in the bookmarks table with `folderName` as the `PARENT_FOLDER` except those with the specified IDs. + String GET_BOOKMARKS_EXCEPT_SPECIFIED = "SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER + " = " + folderName + - " ORDER BY " + DISPLAY_ORDER + " ASC"; + " AND " + _ID + " NOT IN (" + idsNotToGetStringBuilder.toString() + ")"; // Return the result as a cursor. The cursor cannot be closed because it is used in the parent activity. - return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null); + return bookmarksDatabase.rawQuery(GET_BOOKMARKS_EXCEPT_SPECIFIED, null); } - // Get a `Cursor` for all bookmarks and folders in the specified folder except for a specific list of IDs. - public Cursor getBookmarksCursorExcept(long[] exceptIdLongArray, String folderName) { + // Get a cursor for bookmarks and folders in the specified folder by display order except for a specific list of IDs. + public Cursor getBookmarksByDisplayOrderExcept(long[] exceptIdLongArray, String folderName) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); - // Prepare a string builder that contains the comma-separated list of IDs not to get. - StringBuilder doNotGetIdsStringBuilder = new StringBuilder(); + // Prepare a string builder to contain the comma-separated list of IDs not to get. + StringBuilder idsNotToGetStringBuilder = new StringBuilder(); - // Extract the array to `doNotGetIdsString`. + // Extract the array of IDs not to get to the string builder. for (long databaseIdLong : exceptIdLongArray) { - // If this is the first number, only add the number. - if (doNotGetIdsStringBuilder.toString().isEmpty()) { - doNotGetIdsStringBuilder.append(databaseIdLong); - } else { // If there already is a number in the string, place a `,` before the new number. - doNotGetIdsStringBuilder.append(","); - doNotGetIdsStringBuilder.append(databaseIdLong); + if (idsNotToGetStringBuilder.length() == 0) { // This is the first number, so only add the number. + idsNotToGetStringBuilder.append(databaseIdLong); + } else { // This is not the first number, so place a `,` before the new number. + idsNotToGetStringBuilder.append(","); + idsNotToGetStringBuilder.append(databaseIdLong); } } @@ -359,14 +463,13 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { folderName = DatabaseUtils.sqlEscapeString(folderName); // Prepare the SQL statement to select all items except those with the specified IDs. - String GET_All_BOOKMARKS_EXCEPT_SPECIFIED = "SELECT * FROM " + BOOKMARKS_TABLE + + String GET_BOOKMARKS_EXCEPT_SPECIFIED = "SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + PARENT_FOLDER + " = " + folderName + - " AND " + _ID + " NOT IN (" + doNotGetIdsStringBuilder.toString() + + " AND " + _ID + " NOT IN (" + idsNotToGetStringBuilder.toString() + ") ORDER BY " + DISPLAY_ORDER + " ASC"; - // Return the results as a `Cursor`. The second argument is `null` because there are no `selectionArgs`. - // We can't close the `Cursor` because we need to use it in the parent activity. - return bookmarksDatabase.rawQuery(GET_All_BOOKMARKS_EXCEPT_SPECIFIED, null); + // Return the results as a cursor. The cursor cannot be closed because it will be used in the parent activity. + return bookmarksDatabase.rawQuery(GET_BOOKMARKS_EXCEPT_SPECIFIED, null); } // Check if a database ID is a folder. @@ -378,14 +481,14 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { String CHECK_IF_FOLDER = "SELECT * FROM " + BOOKMARKS_TABLE + " WHERE " + _ID + " = " + databaseId; - // Populate folderCursor. The second argument is `null` because there are no `selectionArgs`. + // Populate the folder cursor. Cursor folderCursor = bookmarksDatabase.rawQuery(CHECK_IF_FOLDER, null); // Ascertain if this database ID is a folder. folderCursor.moveToFirst(); boolean isFolder = (folderCursor.getInt(folderCursor.getColumnIndex(IS_FOLDER)) == 1); - // Close the `Cursor` and the database handle. + // Close the cursor and the database handle. folderCursor.close(); bookmarksDatabase.close(); @@ -394,7 +497,7 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { // Update the bookmark name and URL. public void updateBookmark(int databaseId, String bookmarkName, String bookmarkUrl) { - // Initialize a `ContentValues`. + // Initialize a ContentValues. ContentValues bookmarkContentValues = new ContentValues(); // Store the updated values. diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java index 6af6166f..bcec5294 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Soren Stoutner <soren@stoutner.com>. + * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>. * * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. * @@ -158,7 +158,7 @@ public class ImportExportDatabaseHelper { BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(context, null, null, 0); // Get a full bookmarks cursor. - Cursor bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarksCursor(); + Cursor bookmarksCursor = bookmarksDatabaseHelper.getAllBookmarks(); // Move to the first bookmark. bookmarksCursor.moveToFirst(); diff --git a/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml b/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml index 903537aa..378a71e1 100644 --- a/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml +++ b/app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>. + Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>. This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. @@ -47,9 +47,11 @@ android:theme="?attr/appBarTextTheme" /> </android.support.design.widget.AppBarLayout> + <!-- `android:choiceMode="multipleChoiceModal"` allows the contextual action menu to select more than one item at a time. --> <ListView android:id="@+id/bookmarks_databaseview_listview" android:layout_height="match_parent" - android:layout_width="match_parent" /> + android:layout_width="match_parent" + android:choiceMode="multipleChoiceModal" /> </LinearLayout> </android.support.design.widget.CoordinatorLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml b/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml index bc00f778..7911f31d 100644 --- a/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml +++ b/app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>. + Copyright © 2016-2017, 2019 Soren Stoutner <soren@stoutner.com>. This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. @@ -24,7 +24,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_height="wrap_content" android:layout_width="match_parent" - android:orientation="vertical" > + android:orientation="vertical" + android:background="?attr/listSelectorDrawable" > <!-- First row. --> <LinearLayout diff --git a/app/src/main/res/menu/bookmarks_databaseview_context_menu.xml b/app/src/main/res/menu/bookmarks_databaseview_context_menu.xml new file mode 100644 index 00000000..d9daf9d8 --- /dev/null +++ b/app/src/main/res/menu/bookmarks_databaseview_context_menu.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + Copyright © 2019 Soren Stoutner <soren@stoutner.com>. + + This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>. + + Privacy Browser is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Privacy Browser is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. --> + +<menu + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + + <item + android:id="@+id/select_all" + android:title="@string/select_all" + android:orderInCategory="10" + android:icon="?attr/selectAllIcon" + app:showAsAction="ifRoom" /> + + <item + android:id="@+id/delete" + android:title="@string/delete" + android:orderInCategory="20" + android:icon="?attr/deleteIcon" + app:showAsAction="ifRoom" /> +</menu> \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ce453359..628cc795 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -231,6 +231,9 @@ <string name="bookmarks_database_view">ÐÑоÑмоÑÑ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ Ð·Ð°ÐºÐ»Ð°Ð´Ð¾Ðº</string> <string name="all_folders">ÐÑе папки</string> <string name="home_folder">ÐомаÑнÑÑ Ð¿Ð°Ð¿ÐºÐ°</string> + <string name="sort">СоÑÑиÑовка</string> + <string name="sorted_by_database_id">СоÑÑиÑоваÑÑ Ð¿Ð¾ ID Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ .</string> + <string name="sorted_by_display_order">СоÑÑиÑоваÑÑ Ð¿Ð¾ поÑÑÐ´ÐºÑ Ð¾ÑобÑажениÑ.</string> <string name="database_id">ID Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ :</string> <string name="folder">Ðапка:</string> <string name="parent_folder">РодиÑелÑÑÐºÐ°Ñ Ð¿Ð°Ð¿ÐºÐ°:</string> diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index ff7d0567..40922729 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -22,7 +22,7 @@ <!-- Activities. --> <string name="privacy_browser">Privacy Browser</string> <string name="privacy_browser_settings">Privacy Browser Ayarları</string> - <!-- For translations, `android_asset_path` should be the localization abbreviation. For example, Spanish is `es`. This should not be translated unless the Guide and About sections are localized. --> + <!-- For translations, `android_asset_path` should be the localization abbreviation. This should not be translated unless the Guide and About sections are localized. --> <string name="android_asset_path">tr</string> <!-- MainWebView. --> @@ -103,7 +103,7 @@ <!-- MainWebViewActivity Navigation Drawer. --> <string name="navigation_drawer">Açılır Menü</string> - <string name="navigation">Gezinim</string> + <string name="navigation">Gezinti</string> <string name="home">Anasayfa</string> <string name="back">Geri</string> <string name="forward">Ä°leri</string> @@ -230,12 +230,46 @@ <string name="bookmarks_database_view">Yer Ä°mleri Veritabanı Görünümü</string> <string name="all_folders">Tüm Klasörler</string> <string name="home_folder">Ana klasör</string> + <string name="sort">Sırala</string> + <string name="sorted_by_database_id">Veritabanı kimliÄine göre sıralandı.</string> + <string name="sorted_by_display_order">Görüntüleme düzenine göre sıralandı.</string> <string name="database_id">Veritabanı KimliÄi:</string> <string name="folder">Klasör:</string> <string name="parent_folder">Ãst Klasör:</string> - <string name="display_order">Display order:</string> + <string name="display_order">Görüntüleme düzeni:</string> <!-- Requests. --> + <string name="requests">Ä°stekler</string> + <string name="request_details">Ä°stek detayları</string> + <string name="disposition">Ä°Ålem</string> + <string name="all">Tüm</string> + <string name="default_label">Varsayılan</string> + <string name="default_allowed">Varsayılan - Ä°zin verildi</string> + <string name="allowed">Ä°zin verildi</string> + <string name="allowed_plural">Ä°zin verildi</string> + <string name="third_party_plural">Ãçüncü Taraflar</string> + <string name="third_party_blocked">Ãçüncü Taraf - Engellendi</string> + <string name="blocked">Engellendi</string> + <string name="blocked_plural">Engellendi</string> + <string name="blocklist">Engellenenler</string> + <string name="main_whitelist">Ana beyaz liste</string> + <string name="final_whitelist">Final beyaz liste</string> + <string name="domain_whitelist">Domain beyaz listesi</string> + <string name="domain_initial_whitelist">Domain baÅlangıç beyaz listesi</string> + <string name="domain_final_whitelist">Domain final beyaz listesi</string> + <string name="third_party_whitelist">Ãçüncü taraf beyaz listesi</string> + <string name="third_party_domain_whitelist">Ãçüncü taraf domain beyaz listesi</string> + <string name="third_party_domain_initial_whitelist">Ãçüncü taraf domain baÅlangıç beyaz listesi</string> + <string name="main_blacklist">Ana kara liste</string> + <string name="initial_blacklist">BaÅlangıç kara listesi</string> + <string name="final_blacklist">Final kara liste</string> + <string name="domain_blacklist">Domain kara listesi</string> + <string name="domain_initial_blacklist">Domain baÅlangıç kara listesi</string> + <string name="domain_final_blacklist">Domain final kara listesi</string> + <string name="third_party_blacklist">Ãçüncü taraf kara listesi</string> + <string name="third_party_initial_blacklist">Ãçüncü taraf baÅlangıç kara listesi</string> + <string name="third_party_domain_blacklist">Ãçüncü taraf domain kara listesi</string> + <string name="third_party_domain_initial_blacklist">Ãçüncü taraf domain baÅlangıç kara listesi</string> <!-- Domains. --> <string name="domains">Domainler</string> @@ -248,17 +282,17 @@ <string-array name="swipe_to_refresh_array"> <item>Sistem varsayılanı</item> <item>Yenilemek için kaydır etkin</item> - <item>Yenilemek için kaydır devredıÅı</item> + <item>Yenilemek için kaydır devre dıÅı</item> </string-array> <string-array name="night_mode_array"> <item>Sistem varsayılanı</item> <item>Gece modu etkin</item> - <item>Gece modu devredıÅı</item> + <item>Gece modu devre dıÅı</item> </string-array> <string-array name="display_webpage_images_array"> <item>Sistem varsayılanı</item> - <item>Görüntüler etkin</item> - <item>Görüntüler devredıÅı</item> + <item>Resimler etkin</item> + <item>Resimler devre dıÅı</item> </string-array> <string name="pinned_ssl_certificate">Ä°Äneli SSL sertifikası</string> <string name="saved_ssl_certificate">Kayıtlı SSL sertifikası</string> @@ -268,16 +302,22 @@ <!-- Guide. --> <string name="privacy_browser_guide">Privacy Browser Rehberi</string> - <string name="local_storage">Yerel Depolama</string> + <string name="overview">Genel BakıÅ</string> + <string name="local_storage">Yerel Depolama Alanı</string> <string name="ssl_certificates">SSL Sertifikaları</string> + <string name="tracking_ids">Ä°zleme Kimlikleri</string> <!-- Download Location --> <string name="download_location">Ä°ndirme Konumu</string> - <string name="ok">OK</string> + <string name="download_location_message">Privacy Browser\'ın genel indirme dizinini kullanması için depolama alanı izni gerekmektedir. + EÄer reddedilirse, onun yerine uygulamanın indirme dizini kullanılacaktır.</string> <!-- Orbot. --> + <string name="orbot_proxy_not_installed">Orbot yüklenmeden Orbot proxy çalıÅmayacaktır.</string> + <string name="waiting_for_orbot">Orbot\'un baÄlanması bekleniyor...</string> <!-- About Activity. --> + <string name="about_privacy_browser">Privacy Browser Hakkında</string> <string name="version">Sürüm</string> <string name="version_code">Sürüm kodu</string> <string name="hardware">Donanım</string> @@ -285,10 +325,11 @@ <string name="manufacturer">Ãretici:</string> <string name="device">Cihaz:</string> <string name="bootloader">Bootloader:</string> - <string name="radio">Radio:</string> + <string name="radio">Donanım Yazılımı:</string> <string name="software">Yazılım</string> <string name="android">Android:</string> <string name="api">API</string> + <string name="build">Derleme:</string> <string name="security_patch">Güvenlik Yaması:</string> <string name="webview">Web Görünümü:</string> <string name="orbot">Orbot:</string> @@ -298,16 +339,32 @@ <string name="fanboy_annoyance_label">Fanboyâs Annoyance Listesi:</string> <string name="fanboy_social_label">Fanboyâs Social Blocking Listesi:</string> <string name="ultraprivacy_label">UltraPrivacy:</string> + <string name="package_signature">Paket Ä°mzası</string> + <string name="issuer_dn">Yayınlayan DA:</string> + <string name="subject_dn">Ãzne DA:</string> <string name="certificate_version">Sertifika Sürümü:</string> - <string name="serial_number">Serial Number:</string> + <string name="serial_number">Seri Numarası:</string> <string name="signature_algorithm">Ä°mza Algoritması:</string> <string name="permissions">Ä°zinler</string> + <string name="privacy_policy">Privacy Politikası</string> <string name="changelog">DeÄiÅiklik GünlüÄü</string> <string name="licenses">Lisanslar</string> <string name="contributors">Katkıda Bulunanlar</string> <string name="links">Linkler</string> <!-- Preferences. --> + <string name="privacy">Gizlilik</string> + <string name="javascript_preference">JavaScript\'i varsayılan olarak etkinleÅtir</string> + <string name="javascript_preference_summary">JavaScript web sitelerin cihazdaki programları(scriptler) çalıÅtırmasına izin verir.</string> + <string name="first_party_cookies_preference">Birinci taraf çerezleri varsayılan olarak etkinleÅtir</string> + <string name="first_party_cookies_preference_summary">Bu ayar, Android Lollipop sürümünden(5.0) eski sürümlere sahip cihazlarda üçüncü taraf çerezleri de etkinleÅtirir.</string> + <string name="third_party_cookies_preference">Ãçüncü taraf çerezleri varsayılan olarak etkinleÅtir</string> + <string name="third_party_cookies_summary">Bu ayarı etkinleÅtirmek için Android Lollipop sürümüne(5.0) ya da daha üst sürümlere sahip olmak gerekir. + Birinci taraf çerezler devre dıÅı olduÄu takdirde etkisi yoktur.</string> + <string name="dom_storage_preference">DOM depolama alanını varsayılan olarak etkinleÅtir</string> + <string name="dom_storage_preference_summary">DOM depolama alanının çalıÅması için JavaScript\'in etkin olması gerekir.</string> + <string name="save_form_data_preference">Form verisini kaydetmeyi varsayılan olarak etkinleÅtir</string> <!-- The form data strings can be removed once the minimum API >= 26. --> + <string name="save_form_data_preference_summary">Kaydedilen form verisi web sitelerdeki boÅlukları otomatik dolduracaktır.</string> <string name="user_agent">Kullanıcı aracısı</string> <string-array name="translated_user_agent_names"> <item>Privacy Browser</item> @@ -341,11 +398,31 @@ <item>Ãzel</item> </string-array> <string name="custom_user_agent">Ãzel kullanıcı aracısı</string> + <string name="incognito_mode">Gizli Mod</string> + <string name="incognito_mode_summary">Her web sayfasının yüklenmesi bittikten sonra geçmiÅi ve önbelleÄi temizler. Ä°leri ve geri seçenekleri Gizli Mod aktifken çalıÅmaz.</string> + <string name="do_not_track">Takip Etme</string> + <string name="do_not_track_summary">Web Serverlarına, bu tarayıcıyı takip etmemesini nezaketle telkin etmek için Takip Etme BaÅlıÄı gönderir.</string> + <string name="allow_screenshots">Ekran görüntülerine izin ver</string> + <string name="allow_screenshots_summary">Ekran görüntülerine, video kaydına ve güvenli olmayan ekranlarda görüntülenmeye izin verir. + Bu ayarı deÄiÅtirmek Privacy Browser uygulamasını yeniden baÅlatır.</string> + <string name="blocklists">Engellenenler</string> + <string name="easylist">EasyList</string> + <string name="easylist_summary">Ana reklam engelleme listesi.</string> + <string name="easyprivacy">EasyPrivacy</string> + <string name="easyprivacy_summary">Ana takipçi engelleme listesi.</string> + <string name="fanboys_annoyance_list">Fanboyâs annoyance listesi</string> + <string name="fanboys_annoyance_list_summary">Rahatsız eden popupları ve linkleri engeller. Fanboyâs social blocking listesini de içerir.</string> + <string name="fanboys_social_blocking_list">Fanboyâs social blocking listesi</string> + <string name="fanboys_social_blocking_list_summary">Ãçüncü taraf sosyal medya içeriklerini engeller.</string> + <string name="ultraprivacy">UltraPrivacy</string> + <string name="ultraprivacy_summary">UltraPrivacy, EasyPrivacy\'de olmayan takipçileri de engeller fakat bu seçenek bazı web sitelerinin çökmesine sebep olabilir.</string> + <string name="block_all_third_party_requests">Tüm üçüncü taraf istekleri engelle</string> + <string name="block_all_third_party_requests_summary">Tüm üçüncü taraf istekleri engellemek gizliliÄi arttırır, fakat çoÄu web sitesinin çökmesine sebep olur.</string> <string-array name="tor_search_entries"> <item>Searx</item> <item>DuckDuckGo - JavaScript devre dıÅı</item> <item>DuckDuckGo - JavaScript etkin</item> - <item>Custom</item> + <item>Ãzel</item> </string-array> <string name="search">Arama</string> <string-array name="search_entries"> @@ -361,6 +438,24 @@ <item>Yahoo - JavaScript etkin</item> <item>Ãzel</item> </string-array> + <string name="search_custom_url">Ãzel URL Ara</string> + <string name="custom_url">Ãzel URL</string> + <string name="full_screen">Tam Ekran</string> + <string name="full_screen_browsing_mode">Tam ekran modu</string> + <string name="full_screen_browsing_mode_summary">Tam ekran moduna geçmek için çift dokun.</string> + <string name="hide_system_bars">Sistem çubuÄunu gizle</string> + <string name="hide_system_bars_summary">Tam ekran modunda durum ve gezinti çubuÄunu gizler. Tam ekran modundayken klavye açıldıÄında iyi çalıÅmayabilir.</string> + <string name="translucent_navigation_bar">Yarı saydam gezinti çubuÄu</string> + <string name="translucent_navigation_bar_summary">Gezinti çubuÄunu, tam ekran modunda yarı saydam yapar.</string> + <string name="clear_everything">Her Åeyi temizle</string> + <string name="clear_cookies_preference">Ãerezleri temizle</string> + <string name="clear_cookies_summary">Birinci ve Ãçüncü taraf çerezleri temizler</string> + <string name="clear_dom_storage_preference">Dom Depolama Alanını temizle</string> + <string name="clear_dom_storage_summary">Dom Depolama Alanını temizler.</string> + <string name="clear_form_data_preference">Form verisini temizle</string> <!-- The form data strings can be removed once the minimum API >= 26. --> + <string name="clear_form_data_summary">Form verisini temizler.</string> <!-- The form data strings can be removed once the minimum API >= 26. --> + <string name="clear_cache">ÃnbelleÄi temizle</string> + <string name="clear_cache_summary">Web Görünümü önbelleÄini temizler.</string> <string name="general">Genel</string> <string name="homepage">Ana Sayfa</string> <string name="font_size_preference">Yazı tipi boyutu</string> @@ -375,7 +470,7 @@ <item>%200</item> </string-array> <string-array name="domain_settings_font_size_entries"> - <item>System default</item> + <item>Sistem varsayılanı</item> <item>%25</item> <item>%50</item> <item>%75</item> @@ -386,8 +481,16 @@ <item>%200</item> </string-array> <string name="swipe_to_refresh">Yenilemek için kaydır</string> + <string name="swipe_to_refresh_summary">Bazı web siteleri, yenilemek için kaydır seçeneÄi etkin olduÄunda iyi çalıÅmayabilir.</string> + <string name="download_with_external_app">Harici uygulamayla indir</string> + <string name="download_with_external_app_summary">Android indirme yönetecisi bazı cihazlarda iyi çalıÅmayabilir.</string> + <string name="display_additional_app_bar_icons">Ek uygulama çubuÄu simgelerini göster</string> <string name="dark_theme">Koyu tema</string> + <string name="dark_theme_summary">Temayı deÄiÅtirmek Privacy Browser\'ı yeniden baÅlatacak.</string> <string name="night_mode">Gece mody</string> + <string name="night_mode_summary">Gece modunu etkinleÅtirmek aynı zamanda tüm sitelerde JavaScript\'i etkinleÅtirecek.</string> + <string name="display_webpage_images">Web sitesi resimlerini göster</string> + <string name="display_webpage_images_summary">Bant geniÅliÄi korumayı devre dıÅı bırak.</string> <!-- Ad Control. There are no ads in the standard flavor, but these strings must exist because they are referenced in the code. --> <string name="ad_consent">Reklam Onayı</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 19e2bc83..a5dece77 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -246,6 +246,7 @@ <string name="folder">Folder:</string> <string name="parent_folder">Parent folder:</string> <string name="display_order">Display order:</string> + <string name="cannot_deselect_bookmark">A bookmark cannot be deselected while the parent folder is selected.</string> <!-- Requests. --> <string name="requests">Requests</string> @@ -488,7 +489,7 @@ <string name="ultraprivacy">UltraPrivacy</string> <string name="ultraprivacy_summary">UltraPrivacy blocks trackers that EasyPrivacy doesnât because doing so can break websites.</string> <string name="block_all_third_party_requests">Block all third-party requests</string> - <string name="block_all_third_party_requests_summary" translatable="false">Blocking all third-party requests increases privacy, but it breaks many websites.</string> + <string name="block_all_third_party_requests_summary">Blocking all third-party requests increases privacy, but it breaks many websites.</string> <string name="tor">Tor</string> <string name="proxy_through_orbot">Proxy through Orbot</string> <string name="proxy_through_orbot_summary">Proxy all web traffic through Orbot on localhost:8118.</string>